diff mbox

Go patch committed: Use backend interface for expressions

Message ID mcr7g5y7lmj.fsf@iant-glaptop.roam.corp.google.com
State New
Headers show

Commit Message

Ian Lance Taylor May 6, 2014, 7:28 p.m. UTC
This patch by Chris Manghane changes the Go frontend to always use the
backend interface for expressions.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


2014-05-06  Chris Manghane  <cmang@google.com>

	* go-gcc.cc (Gcc_backend::nil_pointer_expression): New method.
	(Gcc_backend::boolean_constant_expression): New method.
	(Gcc_backend::zero_expression): Use this->make_expression rather
	than tree_to_expr.
	(Gcc_backend::var_expression): Likewise.
	(Gcc_backend::integer_constant_expression): Likewise.
	(Gcc_backend::float_constant_expression): Likewise.
	(Gcc_backend::complex_constant_expression): Likewise.
	(Gcc_backend::struct_field_expression): Likewise.
	(tree_to_type, tree_to_expr, tree_to_stat): Remove functions.
	(tree_to_function, tree_to_block): Remove functions.
	(type_to_tree, expr_to_tree, stat_to_tree): Remove functions.
	(block_to_tree, var_to_tree, function_to_tree): Remove functions.
diff mbox

Patch

Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc	(revision 210109)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -8,17 +8,6 @@ 
 
 #include <algorithm>
 
-#include "toplev.h"
-#include "intl.h"
-#include "tree.h"
-#include "stringpool.h"
-#include "stor-layout.h"
-#include "gimple-expr.h"
-#include "tree-iterator.h"
-#include "convert.h"
-#include "real.h"
-#include "realmpfr.h"
-
 #include "go-c.h"
 #include "gogo.h"
 #include "types.h"
@@ -400,18 +389,18 @@  Expression::convert_interface_to_type(Ty
   return Expression::make_compound(check_iface, obj, location);
 }
 
-// Convert an expression to a tree.  This is implemented by the child
-// class.  Not that it is not in general safe to call this multiple
+// Convert an expression to its backend representation.  This is implemented by
+// the child class.  Not that it is not in general safe to call this multiple
 // times for a single expression, but that we don't catch such errors.
 
-tree
-Expression::get_tree(Translate_context* context)
+Bexpression*
+Expression::get_backend(Translate_context* context)
 {
   // The child may have marked this expression as having an error.
   if (this->classification_ == EXPRESSION_ERROR)
-    return error_mark_node;
+    return context->backend()->error_expression();
 
-  return this->do_get_tree(context);
+  return this->do_get_backend(context);
 }
 
 // Return a backend expression for VAL.
@@ -585,9 +574,9 @@  class Error_expression : public Expressi
   do_is_addressable() const
   { return true; }
 
-  tree
-  do_get_tree(Translate_context*)
-  { return error_mark_node; }
+  Bexpression*
+  do_get_backend(Translate_context* context)
+  { return context->backend()->error_expression(); }
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -640,8 +629,8 @@  Type_expression : public Expression
   do_copy()
   { return this; }
 
-  tree
-  do_get_tree(Translate_context*)
+  Bexpression*
+  do_get_backend(Translate_context*)
   { go_unreachable(); }
 
   void do_dump_expression(Ast_dump_context*) const;
@@ -751,10 +740,10 @@  Var_expression::do_address_taken(bool es
     }
 }
 
-// Get the tree for a reference to a variable.
+// Get the backend representation for a reference to a variable.
 
-tree
-Var_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Var_expression::do_get_backend(Translate_context* context)
 {
   Bvariable* bvar = this->variable_->get_backend_variable(context->gogo(),
 							  context->function());
@@ -778,7 +767,7 @@  Var_expression::do_get_tree(Translate_co
   Bexpression* ret = context->backend()->var_expression(bvar, loc);
   if (is_in_heap)
     ret = context->backend()->indirect_expression(btype, ret, true, loc);
-  return expr_to_tree(ret);
+  return ret;
 }
 
 // Ast dump for variable expression.
@@ -823,10 +812,10 @@  Temporary_reference_expression::do_addre
   this->statement_->set_is_address_taken();
 }
 
-// Get a tree referring to the variable.
+// Get a backend expression referring to the variable.
 
-tree
-Temporary_reference_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Temporary_reference_expression::do_get_backend(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
   Bvariable* bvar = this->statement_->get_backend_variable(context);
@@ -845,7 +834,7 @@  Temporary_reference_expression::do_get_t
       Btype* btype = this->type()->base()->get_backend(gogo);
       ret = gogo->backend()->convert_expression(btype, ret, this->location());
     }
-  return expr_to_tree(ret);
+  return ret;
 }
 
 // Ast dump for temporary reference.
@@ -895,19 +884,19 @@  Set_and_use_temporary_expression::do_add
 
 // Return the backend representation.
 
-tree
-Set_and_use_temporary_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Set_and_use_temporary_expression::do_get_backend(Translate_context* context)
 {
   Location loc = this->location();
   Gogo* gogo = context->gogo();
   Bvariable* bvar = this->statement_->get_backend_variable(context);
   Bexpression* var_ref = gogo->backend()->var_expression(bvar, loc);
 
-  Bexpression* bexpr = tree_to_expr(this->expr_->get_tree(context));
+  Bexpression* bexpr = this->expr_->get_backend(context);
   Bstatement* set = gogo->backend()->assignment_statement(var_ref, bexpr, loc);
   var_ref = gogo->backend()->var_expression(bvar, loc);
   Bexpression* ret = gogo->backend()->compound_expression(set, var_ref, loc);
-  return expr_to_tree(ret);
+  return ret;
 }
 
 // Dump.
@@ -957,8 +946,8 @@  class Sink_expression : public Expressio
   do_copy()
   { return new Sink_expression(this->location()); }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -992,8 +981,8 @@  Sink_expression::do_determine_type(const
 // Return a temporary variable for a sink expression.  This will
 // presumably be a write-only variable which the middle-end will drop.
 
-tree
-Sink_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Sink_expression::do_get_backend(Translate_context* context)
 {
   Location loc = this->location();
   Gogo* gogo = context->gogo();
@@ -1010,9 +999,9 @@  Sink_expression::do_get_tree(Translate_c
 					    false, loc, &decl);
       Bexpression* var_ref = gogo->backend()->var_expression(this->bvar_, loc);
       var_ref = gogo->backend()->compound_expression(decl, var_ref, loc);
-      return expr_to_tree(var_ref);
+      return var_ref;
     }
-  return expr_to_tree(gogo->backend()->var_expression(this->bvar_, loc));
+  return gogo->backend()->var_expression(this->bvar_, loc);
 }
 
 // Ast dump for sink expression.
@@ -1061,7 +1050,7 @@  Func_expression::do_type()
     go_unreachable();
 }
 
-// Get the tree for the code of a function expression.
+// Get the backend representation for the code of a function expression.
 
 Bexpression*
 Func_expression::get_code_pointer(Gogo* gogo, Named_object* no, Location loc)
@@ -1095,15 +1084,15 @@  Func_expression::get_code_pointer(Gogo*
   return gogo->backend()->function_code_expression(fndecl, loc);
 }
 
-// Get the tree for a function expression.  This is used when we take
-// the address of a function rather than simply calling it.  A func
+// Get the backend representation for a function expression.  This is used when
+// we take the address of a function rather than simply calling it.  A func
 // value is represented as a pointer to a block of memory.  The first
 // word of that memory is a pointer to the function code.  The
 // remaining parts of that memory are the addresses of variables that
 // the function closes over.
 
-tree
-Func_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Func_expression::do_get_backend(Translate_context* context)
 {
   // If there is no closure, just use the function descriptor.
   if (this->closure_ == NULL)
@@ -1121,17 +1110,15 @@  Func_expression::do_get_tree(Translate_c
 		       ("invalid use of special builtin function %qs; "
 			"must be called"),
 		       no->message_name().c_str());
-	      return error_mark_node;
+	      return gogo->backend()->error_expression();
 	    }
 	  descriptor = no->func_declaration_value()->descriptor(gogo, no);
 	}
       else
 	go_unreachable();
 
-      tree dtree = descriptor->get_tree(context);
-      if (dtree == error_mark_node)
-	return error_mark_node;
-      return build_fold_addr_expr_loc(this->location().gcc_location(), dtree);
+      Bexpression* bdesc = descriptor->get_backend(context);
+      return gogo->backend()->address_expression(bdesc, this->location());
     }
 
   go_assert(this->function_->func_value()->enclosing() != NULL);
@@ -1140,7 +1127,7 @@  Func_expression::do_get_tree(Translate_c
   // expression.  It is a pointer to a struct whose first field points
   // to the function code and whose remaining fields are the addresses
   // of the closed-over variables.
-  return this->closure_->get_tree(context);
+  return this->closure_->get_backend(context);
 }
 
 // Ast dump for function.
@@ -1207,18 +1194,17 @@  Func_descriptor_expression::do_type()
   return Func_descriptor_expression::descriptor_type;
 }
 
-// The tree for a function descriptor.
+// The backend representation for a function descriptor.
 
-tree
-Func_descriptor_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Func_descriptor_expression::do_get_backend(Translate_context* context)
 {
-  if (this->dvar_ != NULL)
-    return var_to_tree(this->dvar_);
-
-  Gogo* gogo = context->gogo();
   Named_object* no = this->fn_;
   Location loc = no->location();
+  if (this->dvar_ != NULL)
+    return context->backend()->var_expression(this->dvar_, loc);
 
+  Gogo* gogo = context->gogo();
   std::string var_name;
   if (no->package() == NULL)
     var_name = gogo->pkgpath_symbol();
@@ -1249,13 +1235,13 @@  Func_descriptor_expression::do_get_tree(
 	Expression::make_struct_composite_literal(this->type(), vals, bloc);
       Translate_context bcontext(gogo, NULL, NULL, NULL);
       bcontext.set_is_const();
-      Bexpression* binit = tree_to_expr(init->get_tree(&bcontext));
+      Bexpression* binit = init->get_backend(&bcontext);
       context->backend()->immutable_struct_set_init(bvar, var_name, is_hidden,
 						    false, btype, bloc, binit);
     }
 
   this->dvar_ = bvar;
-  return var_to_tree(bvar);
+  return gogo->backend()->var_expression(bvar, loc);
 }
 
 // Print a function descriptor expression.
@@ -1316,8 +1302,8 @@  class Func_code_reference_expression : p
 						this->location());
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context* context) const
@@ -1328,15 +1314,13 @@  class Func_code_reference_expression : p
   Named_object* function_;
 };
 
-// Get the tree for a reference to function code.
+// Get the backend representation for a reference to function code.
 
-tree
-Func_code_reference_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Func_code_reference_expression::do_get_backend(Translate_context* context)
 {
-  Bexpression* ret =
-      Func_expression::get_code_pointer(context->gogo(), this->function_,
-                                        this->location());
-  return expr_to_tree(ret);
+  return Func_expression::get_code_pointer(context->gogo(), this->function_,
+					   this->location());
 }
 
 // Make a reference to the code of a function.
@@ -1459,9 +1443,9 @@  class Boolean_expression : public Expres
   do_copy()
   { return this; }
 
-  tree
-  do_get_tree(Translate_context*)
-  { return this->val_ ? boolean_true_node : boolean_false_node; }
+  Bexpression*
+  do_get_backend(Translate_context* context)
+  { return context->backend()->boolean_constant_expression(this->val_); }
 
   void
   do_export(Export* exp) const
@@ -1553,8 +1537,8 @@  String_expression::do_determine_type(con
 
 // Build a string constant.
 
-tree
-String_expression::do_get_tree(Translate_context* context)
+Bexpression*
+String_expression::do_get_backend(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
   Btype* btype = Type::make_string_type()->get_backend(gogo);
@@ -1571,8 +1555,7 @@  String_expression::do_get_tree(Translate
   init[1] = gogo->backend()->integer_constant_expression(int_btype, lenval);
   mpz_clear(lenval);
 
-  Bexpression* ret = gogo->backend()->constructor_expression(btype, init, loc);
-  return expr_to_tree(ret);
+  return gogo->backend()->constructor_expression(btype, init, loc);
 }
 
  // Write string literal to string dump.
@@ -1706,8 +1689,8 @@  class String_info_expression : public Ex
 				      this->location());
   }
 
-  tree
-  do_get_tree(Translate_context* context);
+  Bexpression*
+  do_get_backend(Translate_context* context);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -1744,24 +1727,23 @@  String_info_expression::do_type()
 
 // Return string information in GENERIC.
 
-tree
-String_info_expression::do_get_tree(Translate_context* context)
+Bexpression*
+String_info_expression::do_get_backend(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
 
-  Bexpression* bstring = tree_to_expr(this->string_->get_tree(context));
-  Bexpression* ret;
+  Bexpression* bstring = this->string_->get_backend(context);
   switch (this->string_info_)
     {
     case STRING_INFO_DATA:
     case STRING_INFO_LENGTH:
-      ret = gogo->backend()->struct_field_expression(bstring, this->string_info_,
-                                                     this->location());
+      return gogo->backend()->struct_field_expression(bstring,
+						      this->string_info_,
+						      this->location());
       break;
     default:
       go_unreachable();
     }
-  return expr_to_tree(ret);
 }
 
 // Dump ast representation for a type info expression.
@@ -1832,8 +1814,8 @@  class Integer_expression : public Expres
   void
   do_check_types(Gogo*);
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   Expression*
   do_copy()
@@ -1926,10 +1908,10 @@  Integer_expression::do_check_types(Gogo*
     this->set_is_error();
 }
 
-// Get a tree for an integer constant.
+// Get the backend representation for an integer constant.
 
-tree
-Integer_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Integer_expression::do_get_backend(Translate_context* context)
 {
   Type* resolved_type = NULL;
   if (this->type_ != NULL && !this->type_->is_abstract())
@@ -1961,15 +1943,12 @@  Integer_expression::do_get_tree(Translat
           if (!saw_errors())
             error_at(this->location(),
                      "unknown type for large integer constant");
-          Bexpression* ret = context->gogo()->backend()->error_expression();
-          return expr_to_tree(ret);
+          return context->gogo()->backend()->error_expression();
         }
     }
   Numeric_constant nc;
   nc.set_int(resolved_type, this->val_);
-  Bexpression* ret =
-      Expression::backend_numeric_constant_expression(context, &nc);
-  return expr_to_tree(ret);
+  return Expression::backend_numeric_constant_expression(context, &nc);
 }
 
 // Write VAL to export data.
@@ -2164,8 +2143,8 @@  class Float_expression : public Expressi
   { return Expression::make_float(&this->val_, this->type_,
 				  this->location()); }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_export(Export*) const;
@@ -2222,10 +2201,10 @@  Float_expression::do_check_types(Gogo*)
     this->set_is_error();
 }
 
-// Get a tree for a float constant.
+// Get the backend representation for a float constant.
 
-tree
-Float_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Float_expression::do_get_backend(Translate_context* context)
 {
   Type* resolved_type;
   if (this->type_ != NULL && !this->type_->is_abstract())
@@ -2250,9 +2229,7 @@  Float_expression::do_get_tree(Translate_
 
   Numeric_constant nc;
   nc.set_float(resolved_type, this->val_);
-  Bexpression* ret =
-      Expression::backend_numeric_constant_expression(context, &nc);
-  return expr_to_tree(ret);
+  return Expression::backend_numeric_constant_expression(context, &nc);
 }
 
 // Write a floating point number to a string dump.
@@ -2353,8 +2330,8 @@  class Complex_expression : public Expres
 				    this->location());
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_export(Export*) const;
@@ -2411,10 +2388,10 @@  Complex_expression::do_check_types(Gogo*
     this->set_is_error();
 }
 
-// Get a tree for a complex constant.
+// Get the backend representation for a complex constant.
 
-tree
-Complex_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Complex_expression::do_get_backend(Translate_context* context)
 {
   Type* resolved_type;
   if (this->type_ != NULL && !this->type_->is_abstract())
@@ -2439,9 +2416,7 @@  Complex_expression::do_get_tree(Translat
 
   Numeric_constant nc;
   nc.set_complex(resolved_type, this->real_, this->imag_);
-  Bexpression* ret =
-      Expression::backend_numeric_constant_expression(context, &nc);
-  return expr_to_tree(ret);
+  return Expression::backend_numeric_constant_expression(context, &nc);
 }
 
 // Write REAL/IMAG to export data.
@@ -2568,8 +2543,8 @@  class Const_expression : public Expressi
   do_copy()
   { return this; }
 
-  tree
-  do_get_tree(Translate_context* context);
+  Bexpression*
+  do_get_backend(Translate_context* context);
 
   // When exporting a reference to a const as part of a const
   // expression, we export the value.  We ignore the fact that it has
@@ -2800,13 +2775,13 @@  Const_expression::do_check_types(Gogo*)
     }
 }
 
-// Return a tree for the const reference.
+// Return the backend representation for a const reference.
 
-tree
-Const_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Const_expression::do_get_backend(Translate_context* context)
 {
   if (this->type_ != NULL && this->type_->is_error())
-    return error_mark_node;
+    return context->backend()->error_expression();
 
   // If the type has been set for this expression, but the underlying
   // object is an abstract int or float, we try to get the abstract
@@ -2822,13 +2797,13 @@  Const_expression::do_get_tree(Translate_
 	  && nc.set_type(this->type_, false, this->location()))
 	{
 	  Expression* e = nc.expression(this->location());
-	  return e->get_tree(context);
+	  return e->get_backend(context);
 	}
     }
 
   if (this->type_ != NULL)
     expr = Expression::make_cast(this->type_, expr, this->location());
-  return expr->get_tree(context);
+  return expr->get_backend(context);
 }
 
 // Dump ast representation for constant expression.
@@ -2917,9 +2892,9 @@  class Nil_expression : public Expression
   do_copy()
   { return this; }
 
-  tree
-  do_get_tree(Translate_context*)
-  { return null_pointer_node; }
+  Bexpression*
+  do_get_backend(Translate_context* context)
+  { return context->backend()->nil_pointer_expression(); }
 
   void
   do_export(Export* exp) const
@@ -3060,8 +3035,8 @@  class Type_conversion_expression : publi
 					  this->location());
   }
 
-  tree
-  do_get_tree(Translate_context* context);
+  Bexpression*
+  do_get_backend(Translate_context* context);
 
   void
   do_export(Export*) const;
@@ -3302,32 +3277,28 @@  Type_conversion_expression::do_check_typ
   this->set_is_error();
 }
 
-// Get a tree for a type conversion.
+// Get the backend representation for a type conversion.
 
-tree
-Type_conversion_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Type_conversion_expression::do_get_backend(Translate_context* context)
 {
   Type* type = this->type_;
   Type* expr_type = this->expr_->type();
 
   Gogo* gogo = context->gogo();
   Btype* btype = type->get_backend(gogo);
-  Bexpression* bexpr = tree_to_expr(this->expr_->get_tree(context));
+  Bexpression* bexpr = this->expr_->get_backend(context);
   Location loc = this->location();
 
   if (Type::are_identical(type, expr_type, false, NULL))
-    {
-      Bexpression* bconvert =
-        gogo->backend()->convert_expression(btype, bexpr, loc);
-      return expr_to_tree(bconvert);
-    }
+    return gogo->backend()->convert_expression(btype, bexpr, loc);
   else if (type->interface_type() != NULL
 	   || expr_type->interface_type() != NULL)
     {
       Expression* conversion =
           Expression::convert_for_assignment(gogo, type, this->expr_,
                                              this->location());
-      return conversion->get_tree(context);
+      return conversion->get_backend(context);
     }
   else if (type->is_string_type()
 	   && expr_type->integer_type() != NULL)
@@ -3342,12 +3313,12 @@  Type_conversion_expression::do_get_tree(
 	  Lex::append_char(mpz_get_ui(intval), true, &s, loc);
 	  mpz_clear(intval);
 	  Expression* se = Expression::make_string(s, loc);
-	  return se->get_tree(context);
+	  return se->get_backend(context);
 	}
 
       Expression* i2s_expr =
           Runtime::make_call(Runtime::INT_TO_STRING, loc, 1, this->expr_);
-      return Expression::make_cast(type, i2s_expr, loc)->get_tree(context);
+      return Expression::make_cast(type, i2s_expr, loc)->get_backend(context);
     }
   else if (type->is_string_type() && expr_type->is_slice_type())
     {
@@ -3366,7 +3337,8 @@  Type_conversion_expression::do_get_tree(
         }
       Expression* valptr = a->get_value_pointer(gogo, this->expr_);
       Expression* len = a->get_length(gogo, this->expr_);
-      return Runtime::make_call(code, loc, 2, valptr, len)->get_tree(context);
+      return Runtime::make_call(code, loc, 2, valptr,
+				len)->get_backend(context);
     }
   else if (type->is_slice_type() && expr_type->is_string_type())
     {
@@ -3382,14 +3354,12 @@  Type_conversion_expression::do_get_tree(
 	  code = Runtime::STRING_TO_INT_ARRAY;
 	}
       Expression* s2a = Runtime::make_call(code, loc, 1, this->expr_);
-      return Expression::make_unsafe_cast(type, s2a, loc)->get_tree(context);
+      return Expression::make_unsafe_cast(type, s2a, loc)->get_backend(context);
     }
   else if (type->is_numeric_type())
     {
       go_assert(Type::are_convertible(type, expr_type, NULL));
-      Bexpression* bconvert =
-	gogo->backend()->convert_expression(btype, bexpr, loc);
-      return expr_to_tree(bconvert);
+      return gogo->backend()->convert_expression(btype, bexpr, loc);
     }
   else if ((type->is_unsafe_pointer_type()
 	    && (expr_type->points_to() != NULL
@@ -3399,16 +3369,12 @@  Type_conversion_expression::do_get_tree(
            || (this->may_convert_function_types_
                && type->function_type() != NULL
                && expr_type->function_type() != NULL))
-    {
-      Bexpression* bconvert =
-	gogo->backend()->convert_expression(btype, bexpr, loc);
-      return expr_to_tree(bconvert);
-    }
+    return gogo->backend()->convert_expression(btype, bexpr, loc);
   else
     {
       Expression* conversion =
           Expression::convert_for_assignment(gogo, type, this->expr_, loc);
-      return conversion->get_tree(context);
+      return conversion->get_backend(context);
     }
 }
 
@@ -3490,8 +3456,8 @@  class Unsafe_type_conversion_expression
 						 this->location());
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -3516,8 +3482,8 @@  Unsafe_type_conversion_expression::do_tr
 
 // Convert to backend representation.
 
-tree
-Unsafe_type_conversion_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Unsafe_type_conversion_expression::do_get_backend(Translate_context* context)
 {
   // We are only called for a limited number of cases.
 
@@ -3533,7 +3499,7 @@  Unsafe_type_conversion_expression::do_ge
           && !Type::are_convertible(t, et, NULL))
 	{
 	  go_assert(saw_errors());
-	  return error_mark_node;
+	  return context->backend()->error_expression();
 	}
 
       go_assert(et->struct_type() != NULL
@@ -3569,11 +3535,9 @@  Unsafe_type_conversion_expression::do_ge
 
   Gogo* gogo = context->gogo();
   Btype* btype = t->get_backend(gogo);
-  Bexpression* bexpr = tree_to_expr(this->expr_->get_tree(context));
+  Bexpression* bexpr = this->expr_->get_backend(context);
   Location loc = this->location();
-  Bexpression* ret =
-    gogo->backend()->convert_expression(btype, bexpr, loc);
-  return expr_to_tree(ret);
+  return gogo->backend()->convert_expression(btype, bexpr, loc);
 }
 
 // Dump ast representation for an unsafe type conversion expression.
@@ -4042,10 +4006,10 @@  Unary_expression::do_check_types(Gogo*)
     }
 }
 
-// Get a tree for a unary expression.
+// Get the backend representation for a unary expression.
 
-tree
-Unary_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Unary_expression::do_get_backend(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
   Location loc = this->location();
@@ -4061,23 +4025,18 @@  Unary_expression::do_get_tree(Translate_
 	  Temporary_statement* temp = sut->temporary();
 	  Bvariable* bvar = temp->get_backend_variable(context);
           Bexpression* bvar_expr = gogo->backend()->var_expression(bvar, loc);
-
-          Expression* val = sut->expression();
-          Bexpression* bval = tree_to_expr(val->get_tree(context));
+          Bexpression* bval = sut->expression()->get_backend(context);
 
           Bstatement* bassign =
               gogo->backend()->assignment_statement(bvar_expr, bval, loc);
           Bexpression* bvar_addr =
               gogo->backend()->address_expression(bvar_expr, loc);
-          Bexpression* ret =
-              gogo->backend()->compound_expression(bassign, bvar_addr, loc);
-          return expr_to_tree(ret);
+	  return gogo->backend()->compound_expression(bassign, bvar_addr, loc);
 	}
     }
 
   Bexpression* ret;
-  tree expr = this->expr_->get_tree(context);
-  Bexpression* bexpr = tree_to_expr(expr);
+  Bexpression* bexpr = this->expr_->get_backend(context);
   Btype* btype = this->expr_->type()->get_backend(gogo);
   switch (this->op_)
     {
@@ -4186,17 +4145,14 @@  Unary_expression::do_get_tree(Translate_
 	    if (s >= 4096 || this->issue_nil_check_)
 	      {
                 go_assert(this->expr_->is_variable());
-
-                Expression* nil_expr = Expression::make_nil(loc);
-                Bexpression* nil = tree_to_expr(nil_expr->get_tree(context));
+                Bexpression* nil =
+		  Expression::make_nil(loc)->get_backend(context);
                 Bexpression* compare =
                     gogo->backend()->binary_expression(OPERATOR_EQEQ, bexpr,
                                                        nil, loc);
-
-		Expression* crash_expr =
-		    gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE, loc);
                 Bexpression* crash =
-                    tree_to_expr(crash_expr->get_tree(context));
+		  gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
+				      loc)->get_backend(context);
                 bexpr = gogo->backend()->conditional_expression(btype, compare,
                                                                 crash, bexpr,
                                                                 loc);
@@ -4211,7 +4167,7 @@  Unary_expression::do_get_tree(Translate_
       go_unreachable();
     }
 
-  return expr_to_tree(ret);
+  return ret;
 }
 
 // Export a unary expression.
@@ -5898,10 +5854,10 @@  Binary_expression::do_check_types(Gogo*)
     }
 }
 
-// Get a tree for a binary expression.
+// Get the backend representation for a binary expression.
 
-tree
-Binary_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Binary_expression::do_get_backend(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
   Location loc = this->location();
@@ -5919,12 +5875,8 @@  Binary_expression::do_get_tree(Translate
     case OPERATOR_LE:
     case OPERATOR_GT:
     case OPERATOR_GE:
-      {
-        Bexpression* ret =
-            Expression::comparison(context, this->type_, this->op_,
-                                   this->left_, this->right_, loc);
-        return expr_to_tree(ret);
-      }
+      return Expression::comparison(context, this->type_, this->op_,
+				    this->left_, this->right_, loc);
 
     case OPERATOR_OROR:
     case OPERATOR_ANDAND:
@@ -5960,7 +5912,7 @@  Binary_expression::do_get_tree(Translate
       Expression* string_plus =
           Runtime::make_call(Runtime::STRING_PLUS, loc, 2,
                              this->left_, this->right_);
-      return string_plus->get_tree(context);
+      return string_plus->get_backend(context);
     }
 
   // For complex division Go might want slightly different results than the
@@ -5981,11 +5933,11 @@  Binary_expression::do_get_tree(Translate
 	}
       Expression* complex_div =
           Runtime::make_call(complex_code, loc, 2, this->left_, this->right_);
-      return complex_div->get_tree(context);
+      return complex_div->get_backend(context);
     }
 
-  Bexpression* left = tree_to_expr(this->left_->get_tree(context));
-  Bexpression* right = tree_to_expr(this->right_->get_tree(context));
+  Bexpression* left = this->left_->get_backend(context);
+  Bexpression* right = this->right_->get_backend(context);
 
   Type* type = use_left_type ? left_type : right_type;
   Btype* btype = type->get_backend(gogo);
@@ -6055,12 +6007,12 @@  Binary_expression::do_get_tree(Translate
 
 	  // __go_runtime_error(RUNTIME_ERROR_DIVISION_BY_ZERO)
 	  int errcode = RUNTIME_ERROR_DIVISION_BY_ZERO;
-	  Expression* crash = gogo->runtime_error(errcode, loc);
-          Bexpression* crash_expr = tree_to_expr(crash->get_tree(context));
+	  Bexpression* crash = gogo->runtime_error(errcode,
+						   loc)->get_backend(context);
 
 	  // right == 0 ? (__go_runtime_error(...), 0) : ret
-          ret = gogo->backend()->conditional_expression(btype, check,
-                                                        crash_expr, ret, loc);
+          ret = gogo->backend()->conditional_expression(btype, check, crash,
+							ret, loc);
 	}
 
       if (gogo->check_divide_overflow())
@@ -6107,7 +6059,7 @@  Binary_expression::do_get_tree(Translate
                 {
                   Expression* negate_expr =
                       Expression::make_unary(OPERATOR_MINUS, this->left_, loc);
-                  overflow = tree_to_expr(negate_expr->get_tree(context));
+                  overflow = negate_expr->get_backend(context);
                 }
 	      else
                 overflow = zero_expr;
@@ -6123,7 +6075,7 @@  Binary_expression::do_get_tree(Translate
   mpz_clear(zero);
   mpz_clear(one);
   mpz_clear(neg_one);
-  return expr_to_tree(ret);
+  return ret;
 }
 
 // Export a binary expression.
@@ -6447,8 +6399,8 @@  Expression::comparison(Translate_context
 	}
     }
 
-  Bexpression* left_bexpr = tree_to_expr(left->get_tree(context));
-  Bexpression* right_bexpr = tree_to_expr(right->get_tree(context));
+  Bexpression* left_bexpr = left->get_backend(context);
+  Bexpression* right_bexpr = right->get_backend(context);
 
   Gogo* gogo = context->gogo();
   Bexpression* ret = gogo->backend()->binary_expression(op, left_bexpr,
@@ -6708,10 +6660,10 @@  bme_check_nil(const Method::Field_indexe
   return cond;
 }
 
-// Get the tree for a method value.
+// Get the backend representation for a method value.
 
-tree
-Bound_method_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Bound_method_expression::do_get_backend(Translate_context* context)
 {
   Named_object* thunk = Bound_method_expression::create_thunk(context->gogo(),
 							      this->method_,
@@ -6719,7 +6671,7 @@  Bound_method_expression::do_get_tree(Tra
   if (thunk->is_erroneous())
     {
       go_assert(saw_errors());
-      return error_mark_node;
+      return context->backend()->error_expression();
     }
 
   // FIXME: We should lower this earlier, but we can't lower it in the
@@ -6792,19 +6744,19 @@  Bound_method_expression::do_get_tree(Tra
 	nil_check = Expression::make_binary(OPERATOR_OROR, nil_check, n, loc);
     }
 
-  Bexpression* bme = tree_to_expr(ret->get_tree(context));
+  Bexpression* bme = ret->get_backend(context);
   if (nil_check != NULL)
     {
       Gogo* gogo = context->gogo();
-      Expression* crash =
-	gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE, loc);
-      Bexpression* bcrash = tree_to_expr(crash->get_tree(context));
+      Bexpression* crash =
+	gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
+			    loc)->get_backend(context);
       Btype* btype = ret->type()->get_backend(gogo);
-      Bexpression* bcheck = tree_to_expr(nil_check->get_tree(context));
-      bme = gogo->backend()->conditional_expression(btype, bcheck, bcrash,
+      Bexpression* bcheck = nil_check->get_backend(context);
+      bme = gogo->backend()->conditional_expression(btype, bcheck, crash,
 						    bme, loc);
     }
-  return expr_to_tree(bme);
+  return bme;
 }
 
 // Dump ast representation of a bound method expression.
@@ -6879,8 +6831,8 @@  class Builtin_call_expression : public C
 				       this->location());
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_export(Export*) const;
@@ -8299,10 +8251,10 @@  Builtin_call_expression::do_check_types(
     }
 }
 
-// Return the tree for a builtin function.
+// Return the backend representation for a builtin function.
 
-tree
-Builtin_call_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Builtin_call_expression::do_get_backend(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
   Location location = this->location();
@@ -8324,7 +8276,7 @@  Builtin_call_expression::do_get_tree(Tra
 	if (this->seen_)
 	  {
 	    go_assert(saw_errors());
-	    return error_mark_node;
+	    return context->backend()->error_expression();
 	  }
 	this->seen_ = true;
 	this->seen_ = false;
@@ -8348,7 +8300,7 @@  Builtin_call_expression::do_get_tree(Tra
 		if (this->seen_)
 		  {
 		    go_assert(saw_errors());
-		    return error_mark_node;
+		    return context->backend()->error_expression();
 		  }
 		this->seen_ = true;
 	        val = arg_type->array_type()->get_length(gogo, arg);
@@ -8368,7 +8320,7 @@  Builtin_call_expression::do_get_tree(Tra
 		if (this->seen_)
 		  {
 		    go_assert(saw_errors());
-		    return error_mark_node;
+		    return context->backend()->error_expression();
 		  }
 		this->seen_ = true;
                 val = arg_type->array_type()->get_capacity(gogo, arg);
@@ -8381,7 +8333,7 @@  Builtin_call_expression::do_get_tree(Tra
 	  }
 
 	return Expression::make_cast(int_type, val,
-				     location)->get_tree(context);
+				     location)->get_backend(context);
       }
 
     case BUILTIN_PRINT:
@@ -8460,7 +8412,7 @@  Builtin_call_expression::do_get_tree(Tra
 		else
 		  {
 		    go_assert(saw_errors());
-		    return error_mark_node;
+		    return context->backend()->error_expression();
 		  }
 
                 Expression* call = Runtime::make_call(code, location, 1, arg);
@@ -8483,7 +8435,7 @@  Builtin_call_expression::do_get_tree(Tra
                                                       location);
 	  }
 
-        return print_stmts->get_tree(context);
+        return print_stmts->get_backend(context);
       }
 
     case BUILTIN_PANIC:
@@ -8497,7 +8449,7 @@  Builtin_call_expression::do_get_tree(Tra
 
         Expression* panic =
             Runtime::make_call(Runtime::PANIC, location, 1, arg);
-        return panic->get_tree(context);
+        return panic->get_backend(context);
       }
 
     case BUILTIN_RECOVER:
@@ -8522,7 +8474,7 @@  Builtin_call_expression::do_get_tree(Tra
                                                  location, 0);
         Expression* cond =
             Expression::make_conditional(arg, recover, nil, location);
-        return cond->get_tree(context);
+        return cond->get_backend(context);
       }
 
     case BUILTIN_CLOSE:
@@ -8532,7 +8484,7 @@  Builtin_call_expression::do_get_tree(Tra
 	Expression* arg = args->front();
         Expression* close = Runtime::make_call(Runtime::CLOSE, location,
 					       1, arg);
-        return close->get_tree(context);
+        return close->get_backend(context);
       }
 
     case BUILTIN_SIZEOF:
@@ -8545,7 +8497,7 @@  Builtin_call_expression::do_get_tree(Tra
 	    || nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID)
 	  {
 	    go_assert(saw_errors());
-	    return error_mark_node;
+	    return context->backend()->error_expression();
 	  }
 	Type* uintptr_type = Type::lookup_integer_type("uintptr");
         mpz_t ival;
@@ -8553,7 +8505,7 @@  Builtin_call_expression::do_get_tree(Tra
         Expression* int_cst =
             Expression::make_integer(&ival, uintptr_type, location);
         mpz_clear(ival);
-        return int_cst->get_tree(context);
+        return int_cst->get_backend(context);
       }
 
     case BUILTIN_COPY:
@@ -8607,7 +8559,7 @@  Builtin_call_expression::do_get_tree(Tra
                                               arg1_val, arg2_val, bytecount);
 
         Expression* compound = Expression::make_compound(copy, length, location);
-        return compound->get_tree(context);
+        return compound->get_backend(context);
       }
 
     case BUILTIN_APPEND:
@@ -8650,7 +8602,7 @@  Builtin_call_expression::do_get_tree(Tra
                                                 arg1, arg2_val, arg2_len,
                                                 element_size);
         append = Expression::make_unsafe_cast(arg1->type(), append, location);
-        return append->get_tree(context);
+        return append->get_backend(context);
       }
 
     case BUILTIN_REAL:
@@ -8658,26 +8610,23 @@  Builtin_call_expression::do_get_tree(Tra
       {
 	const Expression_list* args = this->args();
 	go_assert(args != NULL && args->size() == 1);
-	Expression* arg = args->front();
 
         Bexpression* ret;
-        Bexpression* bcomplex = tree_to_expr(arg->get_tree(context));
+        Bexpression* bcomplex = args->front()->get_backend(context);
         if (this->code_ == BUILTIN_REAL)
           ret = gogo->backend()->real_part_expression(bcomplex, location);
         else
           ret = gogo->backend()->imag_part_expression(bcomplex, location);
-        return expr_to_tree(ret);
+        return ret;
       }
 
     case BUILTIN_COMPLEX:
       {
 	const Expression_list* args = this->args();
 	go_assert(args != NULL && args->size() == 2);
-	Bexpression* breal = tree_to_expr(args->front()->get_tree(context));
-	Bexpression* bimag = tree_to_expr(args->back()->get_tree(context));
-        Bexpression* ret =
-            gogo->backend()->complex_expression(breal, bimag, location);
-        return expr_to_tree(ret);
+	Bexpression* breal = args->front()->get_backend(context);
+	Bexpression* bimag = args->back()->get_backend(context);
+	return gogo->backend()->complex_expression(breal, bimag, location);
       }
 
     default:
@@ -9400,18 +9349,18 @@  Call_expression::interface_method_functi
 
 // Build the call expression.
 
-tree
-Call_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Call_expression::do_get_backend(Translate_context* context)
 {
   if (this->call_ != NULL)
-    return expr_to_tree(this->call_);
+    return this->call_;
 
   Function_type* fntype = this->get_function_type();
   if (fntype == NULL)
-    return error_mark_node;
+    return context->backend()->error_expression();
 
   if (this->fn_->is_error_expression())
-    return error_mark_node;
+    return context->backend()->error_expression();
 
   Gogo* gogo = context->gogo();
   Location location = this->location();
@@ -9448,7 +9397,7 @@  Call_expression::do_get_tree(Translate_c
 		&& this->args_->size() == 1);
       nargs = 1;
       fn_args.resize(1);
-      fn_args[0] = tree_to_expr(this->args_->front()->get_tree(context));
+      fn_args[0] = this->args_->front()->get_backend(context);
     }
   else
     {
@@ -9463,7 +9412,7 @@  Call_expression::do_get_tree(Translate_c
       Expression_list::const_iterator pe = this->args_->begin();
       if (!is_interface_method && fntype->is_method())
 	{
-          fn_args[i] = tree_to_expr((*pe)->get_tree(context));
+          fn_args[i] = (*pe)->get_backend(context);
 	  ++pe;
 	  ++i;
 	}
@@ -9473,7 +9422,7 @@  Call_expression::do_get_tree(Translate_c
           Expression* arg =
               Expression::convert_for_assignment(gogo, pp->type(), *pe,
                                                  location);
-          fn_args[i] = tree_to_expr(arg->get_tree(context));
+          fn_args[i] = arg->get_backend(context);
 	}
       go_assert(pp == params->end());
       go_assert(i == nargs);
@@ -9504,7 +9453,7 @@  Call_expression::do_get_tree(Translate_c
     {
       Expression* first_arg;
       fn = this->interface_method_function(interface_method, &first_arg);
-      fn_args[0] = tree_to_expr(first_arg->get_tree(context));
+      fn_args[0] = first_arg->get_backend(context);
     }
 
   if (!has_closure_arg)
@@ -9521,7 +9470,7 @@  Call_expression::do_get_tree(Translate_c
       fn = Expression::make_compound(set_closure, fn, location);
     }
 
-  Bexpression* bfn = tree_to_expr(fn->get_tree(context));
+  Bexpression* bfn = fn->get_backend(context);
 
   // When not calling a named function directly, use a type conversion
   // in case the type of the function is a recursive type which refers
@@ -9542,7 +9491,7 @@  Call_expression::do_get_tree(Translate_c
       go_assert(this->call_temp_ != NULL);
       Expression* call_ref =
           Expression::make_temporary_reference(this->call_temp_, location);
-      Bexpression* bcall_ref = tree_to_expr(call_ref->get_tree(context));
+      Bexpression* bcall_ref = call_ref->get_backend(context);
       Bstatement* assn_stmt =
           gogo->backend()->assignment_statement(bcall_ref, call, location);
 
@@ -9551,11 +9500,11 @@  Call_expression::do_get_tree(Translate_c
       Bexpression* set_and_call =
           gogo->backend()->compound_expression(assn_stmt, this->call_,
                                                location);
-      return expr_to_tree(set_and_call);
+      return set_and_call;
     }
 
   this->call_ = call;
-  return expr_to_tree(this->call_);
+  return this->call_;
 }
 
 // Set the result variables if this call returns multiple results.
@@ -9581,7 +9530,7 @@  Call_expression::set_results(Translate_c
 	Expression::make_temporary_reference(temp, loc);
       ref->set_is_lvalue();
 
-      Bexpression* result_ref = tree_to_expr(ref->get_tree(context));
+      Bexpression* result_ref = ref->get_backend(context);
       Bexpression* call_result =
           gogo->backend()->struct_field_expression(call, i, loc);
       Bstatement* assn_stmt =
@@ -9658,8 +9607,8 @@  class Call_result_expression : public Ex
   do_must_eval_in_order() const
   { return true; }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -9754,27 +9703,27 @@  Call_result_expression::do_determine_typ
   this->call_->determine_type_no_context();
 }
 
-// Return the tree.  We just refer to the temporary set by the call
-// expression.  We don't do this at lowering time because it makes it
+// Return the backend representation.  We just refer to the temporary set by the
+// call expression.  We don't do this at lowering time because it makes it
 // hard to evaluate the call at the right time.
 
-tree
-Call_result_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Call_result_expression::do_get_backend(Translate_context* context)
 {
   Call_expression* ce = this->call_->call_expression();
   if (ce == NULL)
     {
       go_assert(this->call_->is_error_expression());
-      return error_mark_node;
+      return context->backend()->error_expression();
     }
   Temporary_statement* ts = ce->result(this->index_);
   if (ts == NULL)
     {
       go_assert(saw_errors());
-      return error_mark_node;
+      return context->backend()->error_expression();
     }
   Expression* ref = Expression::make_temporary_reference(ts, this->location());
-  return ref->get_tree(context);
+  return ref->get_backend(context);
 }
 
 // Dump ast representation for a call result expression.
@@ -9988,8 +9937,8 @@  class Array_index_expression : public Ex
   do_issue_nil_check()
   { this->array_->issue_nil_check(); }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -10253,16 +10202,16 @@  Array_index_expression::do_is_addressabl
   return this->array_->is_addressable();
 }
 
-// Get a tree for an array index.
+// Get the backend representation for an array index.
 
-tree
-Array_index_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Array_index_expression::do_get_backend(Translate_context* context)
 {
   Array_type* array_type = this->array_->type()->array_type();
   if (array_type == NULL)
     {
       go_assert(this->array_->type()->is_error());
-      return error_mark_node;
+      return context->backend()->error_expression();
     }
   go_assert(!array_type->is_slice_type() || this->array_->is_variable());
 
@@ -10279,7 +10228,7 @@  Array_index_expression::do_get_tree(Tran
   if (this->end_ == NULL || this->end_->is_nil_expression())
     {
       Expression* len = array_type->get_length(gogo, this->array_);
-      length = tree_to_expr(len->get_tree(context));
+      length = len->get_backend(context);
       length = gogo->backend()->convert_expression(int_btype, length, loc);
     }
 
@@ -10287,14 +10236,14 @@  Array_index_expression::do_get_tree(Tran
   if (this->end_ != NULL)
     {
       Expression* cap = array_type->get_capacity(gogo, this->array_);
-      capacity = tree_to_expr(cap->get_tree(context));
+      capacity = cap->get_backend(context);
       capacity = gogo->backend()->convert_expression(int_btype, capacity, loc);
     }
 
   Bexpression* cap_arg = capacity;
   if (this->cap_ != NULL)
     {
-      cap_arg = tree_to_expr(this->cap_->get_tree(context));
+      cap_arg = this->cap_->get_backend(context);
       cap_arg = gogo->backend()->convert_expression(int_btype, cap_arg, loc);
     }
 
@@ -10308,13 +10257,12 @@  Array_index_expression::do_get_tree(Tran
 	      : (this->end_ == NULL
 		 ? RUNTIME_ERROR_SLICE_INDEX_OUT_OF_BOUNDS
 		 : RUNTIME_ERROR_SLICE_SLICE_OUT_OF_BOUNDS));
-  Bexpression* crash =
-      tree_to_expr(gogo->runtime_error(code, loc)->get_tree(context));
+  Bexpression* crash = gogo->runtime_error(code, loc)->get_backend(context);
 
-  Expression* bounds_check = Expression::check_bounds(this->start_, loc);
-  Bexpression* bad_index = tree_to_expr(bounds_check->get_tree(context));
+  Bexpression* bad_index =
+    Expression::check_bounds(this->start_, loc)->get_backend(context);
 
-  Bexpression* start = tree_to_expr(this->start_->get_tree(context));
+  Bexpression* start = this->start_->get_backend(context);
   start = gogo->backend()->convert_expression(int_btype, start, loc);
   Bexpression* start_too_large =
     gogo->backend()->binary_expression((this->end_ == NULL
@@ -10339,7 +10287,7 @@  Array_index_expression::do_get_tree(Tran
       Bexpression* ret;
       if (array_type->length() != NULL)
 	{
-	  Bexpression* array = tree_to_expr(this->array_->get_tree(context));
+	  Bexpression* array = this->array_->get_backend(context);
 	  ret = gogo->backend()->array_index_expression(array, start, loc);
 	}
       else
@@ -10347,23 +10295,22 @@  Array_index_expression::do_get_tree(Tran
 	  // Slice.
 	  Expression* valptr =
               array_type->get_value_pointer(gogo, this->array_);
-	  Bexpression* ptr = tree_to_expr(valptr->get_tree(context));
+	  Bexpression* ptr = valptr->get_backend(context);
           ptr = gogo->backend()->pointer_offset_expression(ptr, start, loc);
 
 	  Type* ele_type = this->array_->type()->array_type()->element_type();
 	  Btype* ele_btype = ele_type->get_backend(gogo);
 	  ret = gogo->backend()->indirect_expression(ele_btype, ptr, true, loc);
 	}
-      return expr_to_tree(ret);
+      return ret;
     }
 
   // Array slice.
 
   if (this->cap_ != NULL)
     {
-      bounds_check = Expression::check_bounds(this->cap_, loc);
       Bexpression* bounds_bcheck =
-	tree_to_expr(bounds_check->get_tree(context));
+	Expression::check_bounds(this->cap_, loc)->get_backend(context);
       bad_index =
 	gogo->backend()->binary_expression(OPERATOR_OROR, bounds_bcheck,
 					   bad_index, loc);
@@ -10385,15 +10332,14 @@  Array_index_expression::do_get_tree(Tran
     end = length;
   else
     {
-      bounds_check = Expression::check_bounds(this->end_, loc);
       Bexpression* bounds_bcheck =
-	tree_to_expr(bounds_check->get_tree(context));
+	Expression::check_bounds(this->end_, loc)->get_backend(context);
 
       bad_index =
 	gogo->backend()->binary_expression(OPERATOR_OROR, bounds_bcheck,
 					   bad_index, loc);
 
-      end = tree_to_expr(this->end_->get_tree(context));
+      end = this->end_->get_backend(context);
       end = gogo->backend()->convert_expression(int_btype, end, loc);
       Bexpression* end_too_small =
 	gogo->backend()->binary_expression(OPERATOR_LT, end, start, loc);
@@ -10407,7 +10353,7 @@  Array_index_expression::do_get_tree(Tran
     }
 
   Expression* valptr = array_type->get_value_pointer(gogo, this->array_);
-  Bexpression* val = tree_to_expr(valptr->get_tree(context));
+  Bexpression* val = valptr->get_backend(context);
   val = gogo->backend()->pointer_offset_expression(val, start, loc);
 
   Bexpression* result_length =
@@ -10424,11 +10370,8 @@  Array_index_expression::do_get_tree(Tran
 
   Bexpression* ctor =
     gogo->backend()->constructor_expression(struct_btype, init, loc);
-  Bexpression* ret =
-    gogo->backend()->conditional_expression(struct_btype, bad_index,
-					    crash, ctor, loc);
-
-  return expr_to_tree(ret);
+  return gogo->backend()->conditional_expression(struct_btype, bad_index,
+						 crash, ctor, loc);
 }
 
 // Dump ast representation for an array index expression.
@@ -10496,8 +10439,8 @@  class String_index_expression : public E
     return true;
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -10639,10 +10582,10 @@  String_index_expression::do_check_types(
     mpz_clear(ival);
 }
 
-// Get a tree for a string index.
+// Get the backend representation for a string index.
 
-tree
-String_index_expression::do_get_tree(Translate_context* context)
+Bexpression*
+String_index_expression::do_get_backend(Translate_context* context)
 {
   Location loc = this->location();
   Expression* string_arg = this->string_;
@@ -10656,8 +10599,7 @@  String_index_expression::do_get_tree(Tra
 	      : RUNTIME_ERROR_STRING_SLICE_OUT_OF_BOUNDS);
 
   Gogo* gogo = context->gogo();
-  Bexpression* crash =
-      tree_to_expr(gogo->runtime_error(code, loc)->get_tree(context));
+  Bexpression* crash = gogo->runtime_error(code, loc)->get_backend(context);
 
   Type* int_type = Type::lookup_integer_type("int");
 
@@ -10670,7 +10612,7 @@  String_index_expression::do_get_tree(Tra
       && !Type::are_convertible(int_type, this->start_->type(), NULL))
     {
       go_assert(saw_errors());
-      return error_mark_node;
+      return context->backend()->error_expression();
     }
 
   Expression* start = Expression::make_cast(int_type, this->start_, loc);
@@ -10687,19 +10629,17 @@  String_index_expression::do_get_tree(Tra
       Expression* bytes =
 	Expression::make_string_info(this->string_, STRING_INFO_DATA, loc);
 
-      Bexpression* bstart = tree_to_expr(start->get_tree(context));
-      Bexpression* ptr = tree_to_expr(bytes->get_tree(context));
+      Bexpression* bstart = start->get_backend(context);
+      Bexpression* ptr = bytes->get_backend(context);
       ptr = gogo->backend()->pointer_offset_expression(ptr, bstart, loc);
       Btype* ubtype = Type::lookup_integer_type("uint8")->get_backend(gogo);
       Bexpression* index = 
 	gogo->backend()->indirect_expression(ubtype, ptr, true, loc);
 
       Btype* byte_btype = bytes->type()->points_to()->get_backend(gogo);
-      Bexpression* index_error = tree_to_expr(bad_index->get_tree(context));
-      Bexpression* ret =
-          gogo->backend()->conditional_expression(byte_btype, index_error,
-                                                  crash, index, loc);
-      return expr_to_tree(ret);
+      Bexpression* index_error = bad_index->get_backend(context);
+      return gogo->backend()->conditional_expression(byte_btype, index_error,
+						     crash, index, loc);
     }
 
   Expression* end = NULL;
@@ -10720,14 +10660,12 @@  String_index_expression::do_get_tree(Tra
 
   Expression* strslice = Runtime::make_call(Runtime::STRING_SLICE, loc, 3,
                                             string_arg, start, end);
-  Bexpression* bstrslice = tree_to_expr(strslice->get_tree(context));
+  Bexpression* bstrslice = strslice->get_backend(context);
 
   Btype* str_btype = strslice->type()->get_backend(gogo);
-  Bexpression* index_error = tree_to_expr(bad_index->get_tree(context));
-  Bexpression* ret =
-      gogo->backend()->conditional_expression(str_btype, index_error,
-                                              crash, bstrslice, loc);
-  return expr_to_tree(ret);
+  Bexpression* index_error = bad_index->get_backend(context);
+  return gogo->backend()->conditional_expression(str_btype, index_error,
+						 crash, bstrslice, loc);
 }
 
 // Dump ast representation for a string index expression.
@@ -10862,16 +10800,16 @@  Map_index_expression::do_check_types(Gog
     }
 }
 
-// Get a tree for a map index.
+// Get the backend representation for a map index.
 
-tree
-Map_index_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Map_index_expression::do_get_backend(Translate_context* context)
 {
   Map_type* type = this->get_map_type();
   if (type == NULL)
     {
       go_assert(saw_errors());
-      return error_mark_node;
+      return context->backend()->error_expression();
     }
 
   go_assert(this->value_pointer_ != NULL
@@ -10883,13 +10821,13 @@  Map_index_expression::do_get_tree(Transl
       Expression* val =
           Expression::make_unary(OPERATOR_MULT, this->value_pointer_,
                                  this->location());
-      ret = tree_to_expr(val->get_tree(context));
+      ret = val->get_backend(context);
     }
   else if (this->is_in_tuple_assignment_)
     {
       // Tuple_map_assignment_statement is responsible for using this
       // appropriately.
-      ret = tree_to_expr(this->value_pointer_->get_tree(context));
+      ret = this->value_pointer_->get_backend(context);
     }
   else
     {
@@ -10898,10 +10836,10 @@  Map_index_expression::do_get_tree(Transl
       Expression* nil_check =
           Expression::make_binary(OPERATOR_EQEQ, this->value_pointer_,
                                   Expression::make_nil(loc), loc);
-      Bexpression* bnil_check = tree_to_expr(nil_check->get_tree(context));
+      Bexpression* bnil_check = nil_check->get_backend(context);
       Expression* val =
           Expression::make_unary(OPERATOR_MULT, this->value_pointer_, loc);
-      Bexpression* bval = tree_to_expr(val->get_tree(context));
+      Bexpression* bval = val->get_backend(context);
 
       Gogo* gogo = context->gogo();
       Btype* val_btype = type->val_type()->get_backend(gogo);
@@ -10909,8 +10847,7 @@  Map_index_expression::do_get_tree(Transl
       ret = gogo->backend()->conditional_expression(val_btype, bnil_check,
                                                     val_zero, bval, loc);
     }
-
-  return expr_to_tree(ret);
+  return ret;
 }
 
 // Get an expression for the map index.  This returns an expression which
@@ -11093,17 +11030,15 @@  Field_reference_expression::do_check_typ
   go_assert(struct_type->field(this->field_index_) != NULL);
 }
 
-// Get a tree for a field reference.
+// Get the backend representation for a field reference.
 
-tree
-Field_reference_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Field_reference_expression::do_get_backend(Translate_context* context)
 {
-  Bexpression* bstruct = tree_to_expr(this->expr_->get_tree(context));
-  Bexpression* ret =
-      context->gogo()->backend()->struct_field_expression(bstruct,
-                                                          this->field_index_,
-                                                          this->location());
-  return expr_to_tree(ret);
+  Bexpression* bstruct = this->expr_->get_backend(context);
+  return context->gogo()->backend()->struct_field_expression(bstruct,
+							     this->field_index_,
+							     this->location());
 }
 
 // Dump ast representation for a field reference expression.
@@ -11363,16 +11298,16 @@  Interface_field_reference_expression::cr
   return new_no;
 }
 
-// Get a tree for a method value.
+// Get the backend representation for a method value.
 
-tree
-Interface_field_reference_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Interface_field_reference_expression::do_get_backend(Translate_context* context)
 {
   Interface_type* type = this->expr_->type()->interface_type();
   if (type == NULL)
     {
       go_assert(saw_errors());
-      return error_mark_node;
+      return context->backend()->error_expression();
     }
 
   Named_object* thunk =
@@ -11381,7 +11316,7 @@  Interface_field_reference_expression::do
   if (thunk->is_erroneous())
     {
       go_assert(saw_errors());
-      return error_mark_node;
+      return context->backend()->error_expression();
     }
 
   // FIXME: We should lower this earlier, but we can't it lower it in
@@ -11405,24 +11340,22 @@  Interface_field_reference_expression::do
   vals->push_back(this->expr_);
 
   Expression* expr = Expression::make_struct_composite_literal(st, vals, loc);
-  expr = Expression::make_heap_expression(expr, loc);
+  Bexpression* bclosure =
+    Expression::make_heap_expression(expr, loc)->get_backend(context);
 
-  Bexpression* bclosure = tree_to_expr(expr->get_tree(context));
   Expression* nil_check =
       Expression::make_binary(OPERATOR_EQEQ, this->expr_,
                               Expression::make_nil(loc), loc);
-  Bexpression* bnil_check = tree_to_expr(nil_check->get_tree(context));
+  Bexpression* bnil_check = nil_check->get_backend(context);
 
   Gogo* gogo = context->gogo();
-  Expression* crash = gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE, loc);
-  Bexpression* bcrash = tree_to_expr(crash->get_tree(context));
+  Bexpression* bcrash = gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
+					    loc)->get_backend(context);
 
   Bexpression* bcond =
       gogo->backend()->conditional_expression(NULL, bnil_check, bcrash, NULL, loc);
   Bstatement* cond_statement = gogo->backend()->expression_statement(bcond);
-  Bexpression* ret =
-      gogo->backend()->compound_expression(cond_statement, bclosure, loc);
-  return expr_to_tree(ret);
+  return gogo->backend()->compound_expression(cond_statement, bclosure, loc);
 }
 
 // Dump ast representation for an interface field reference.
@@ -11741,8 +11674,8 @@  class Allocation_expression : public Exp
   do_copy()
   { return new Allocation_expression(this->type_, this->location()); }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -11752,18 +11685,17 @@  class Allocation_expression : public Exp
   Type* type_;
 };
 
-// Return a tree for an allocation expression.
+// Return the backend representation for an allocation expression.
 
-tree
-Allocation_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Allocation_expression::do_get_backend(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
   Location loc = this->location();
-  Expression* space = gogo->allocate_memory(this->type_, loc);
-  Bexpression* bspace = tree_to_expr(space->get_tree(context));
+  Bexpression* space = 
+    gogo->allocate_memory(this->type_, loc)->get_backend(context);
   Btype* pbtype = gogo->backend()->pointer_type(this->type_->get_backend(gogo));
-  Bexpression* ret = gogo->backend()->convert_expression(pbtype, bspace, loc);
-  return expr_to_tree(ret);
+  return gogo->backend()->convert_expression(pbtype, space, loc);
 }
 
 // Dump ast representation for an allocation expression.
@@ -11834,8 +11766,8 @@  class Struct_construction_expression : p
     return ret;
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_export(Export*) const;
@@ -12008,16 +11940,16 @@  Struct_construction_expression::do_check
   go_assert(pv == this->vals_->end());
 }
 
-// Return a tree for constructing a struct.
+// Return the backend representation for constructing a struct.
 
-tree
-Struct_construction_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Struct_construction_expression::do_get_backend(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
 
   Btype* btype = this->type_->get_backend(gogo);
   if (this->vals_ == NULL)
-    return expr_to_tree(gogo->backend()->zero_expression(btype));
+    return gogo->backend()->zero_expression(btype);
 
   const Struct_field_list* fields = this->type_->struct_type()->fields();
   Expression_list::const_iterator pv = this->vals_->begin();
@@ -12039,14 +11971,11 @@  Struct_construction_expression::do_get_t
           Expression* val =
               Expression::convert_for_assignment(gogo, pf->type(),
                                                  *pv, this->location());
-          init.push_back(tree_to_expr(val->get_tree(context)));
+          init.push_back(val->get_backend(context));
 	  ++pv;
 	}
     }
-
-  Bexpression* ret =
-      gogo->backend()->constructor_expression(btype, init, this->location());
-  return expr_to_tree(ret);
+  return gogo->backend()->constructor_expression(btype, init, this->location());
 }
 
 // Export a struct construction.
@@ -12298,7 +12227,7 @@  Array_construction_expression::get_const
               Expression* val_expr =
                   Expression::convert_for_assignment(gogo, element_type, *pv,
                                                      this->location());
-	      vals.push_back(tree_to_expr(val_expr->get_tree(context)));
+	      vals.push_back(val_expr->get_backend(context));
 	    }
 	  if (this->indexes_ != NULL)
 	    ++pi;
@@ -12407,18 +12336,18 @@  class Fixed_array_construction_expressio
 						   this->location());
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 };
 
-// Return a tree for constructing a fixed array.
+// Return the backend representation for constructing a fixed array.
 
-tree
-Fixed_array_construction_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Fixed_array_construction_expression::do_get_backend(Translate_context* context)
 {
   Type* type = this->type();
   Btype* btype = type->get_backend(context->gogo());
-  return expr_to_tree(this->get_constructor(context, btype));
+  return this->get_constructor(context, btype);
 }
 
 Expression*
@@ -12455,24 +12384,24 @@  class Slice_construction_expression : pu
 					     this->location());
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
  private:
   // The type of the values in this slice.
   Type* valtype_;
 };
 
-// Return a tree for constructing a slice.
+// Return the backend representation for constructing a slice.
 
-tree
-Slice_construction_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Slice_construction_expression::do_get_backend(Translate_context* context)
 {
   Array_type* array_type = this->type()->array_type();
   if (array_type == NULL)
     {
       go_assert(this->type()->is_error());
-      return error_mark_node;
+      return context->backend()->error_expression();
     }
 
   Location loc = this->location();
@@ -12533,7 +12462,7 @@  Slice_construction_expression::do_get_tr
   Expression* len = this->valtype_->array_type()->length();
   Expression* slice_val =
     Expression::make_slice_value(this->type(), space, len, len, loc);
-  return slice_val->get_tree(context);
+  return slice_val->get_backend(context);
 }
 
 // Make a slice composite literal.  This is used by the type
@@ -12582,8 +12511,8 @@  class Map_construction_expression : publ
 					   this->location());
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_export(Export*) const;
@@ -12734,13 +12663,13 @@  Map_construction_expression::do_check_ty
     }
 }
 
-// Return a tree for constructing a map.
+// Return the backend representation for constructing a map.
 
-tree
-Map_construction_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Map_construction_expression::do_get_backend(Translate_context* context)
 {
   if (this->is_error_expression())
-    return error_mark_node;
+    return context->backend()->error_expression();
   Location loc = this->location();
 
   size_t i = 0;
@@ -12785,7 +12714,7 @@  Map_construction_expression::do_get_tree
   Expression* map_ctor =
       Runtime::make_call(Runtime::CONSTRUCT_MAP, loc, 6, descriptor, count,
                          entry_size, val_offset, val_size, ventries);
-  return map_ctor->get_tree(context);
+  return map_ctor->get_backend(context);
 }
 
 // Export an array construction.
@@ -13654,10 +13583,10 @@  Type_guard_expression::do_check_types(Go
     }
 }
 
-// Return a tree for a type guard expression.
+// Return the backend representation for a type guard expression.
 
-tree
-Type_guard_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Type_guard_expression::do_get_backend(Translate_context* context)
 {
   Expression* conversion;
   if (this->type_->interface_type() != NULL)
@@ -13669,7 +13598,7 @@  Type_guard_expression::do_get_tree(Trans
         Expression::convert_for_assignment(context->gogo(), this->type_,
                                            this->expr_, this->location());
 
-  return conversion->get_tree(context);
+  return conversion->get_backend(context);
 }
 
 // Dump ast representation for a type guard expression.
@@ -13725,8 +13654,8 @@  class Heap_expression : public Expressio
                                             this->location());
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   // We only export global objects, and the parser does not generate
   // this in global scope.
@@ -13742,19 +13671,19 @@  class Heap_expression : public Expressio
   Expression* expr_;
 };
 
-// Return a tree which allocates an expression on the heap.
+// Return the backend representation for allocating an expression on the heap.
 
-tree
-Heap_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Heap_expression::do_get_backend(Translate_context* context)
 {
   if (this->expr_->is_error_expression() || this->expr_->type()->is_error())
-    return error_mark_node;
+    return context->backend()->error_expression();
 
   Location loc = this->location();
   Gogo* gogo = context->gogo();
   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));
+  Bexpression* space = Expression::make_allocation(this->expr_->type(),
+						   loc)->get_backend(context);
 
   Bstatement* decl;
   Named_object* fn = context->function();
@@ -13768,12 +13697,11 @@  Heap_expression::do_get_tree(Translate_c
   Bexpression* ref =
     gogo->backend()->indirect_expression(expr_btype, space, true, loc);
 
-  Bexpression* bexpr = tree_to_expr(this->expr_->get_tree(context));
+  Bexpression* bexpr = this->expr_->get_backend(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);
+  return gogo->backend()->compound_expression(decl, space, loc);
 }
 
 // Dump ast representation for a heap expression.
@@ -13857,10 +13785,10 @@  Receive_expression::do_flatten(Gogo*, Na
   return this;
 }
 
-// Get a tree for a receive expression.
+// Get the backend representation for a receive expression.
 
-tree
-Receive_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Receive_expression::do_get_backend(Translate_context* context)
 {
   Location loc = this->location();
 
@@ -13868,7 +13796,7 @@  Receive_expression::do_get_tree(Translat
   if (channel_type == NULL)
     {
       go_assert(this->channel_->type()->is_error());
-      return error_mark_node;
+      return context->backend()->error_expression();
     }
   Expression* td = Expression::make_type_descriptor(channel_type, loc);
 
@@ -13880,8 +13808,7 @@  Receive_expression::do_get_tree(Translat
   Expression* recv =
     Runtime::make_call(Runtime::RECEIVE, loc, 3,
 		       td, this->channel_, recv_addr);
-  recv = Expression::make_compound(recv, recv_ref, loc);
-  return recv->get_tree(context);
+  return Expression::make_compound(recv, recv_ref, loc)->get_backend(context);
 }
 
 // Dump ast representation for a receive expression.
@@ -13929,12 +13856,11 @@  class Type_descriptor_expression : publi
   do_copy()
   { return this; }
 
-  tree
-  do_get_tree(Translate_context* context)
+  Bexpression*
+  do_get_backend(Translate_context* context)
   {
-    Bexpression* ret = this->type_->type_descriptor_pointer(context->gogo(),
-                                                            this->location());
-    return expr_to_tree(ret);
+    return this->type_->type_descriptor_pointer(context->gogo(),
+						this->location());
   }
 
   void
@@ -13992,8 +13918,8 @@  class Type_info_expression : public Expr
   do_copy()
   { return this; }
 
-  tree
-  do_get_tree(Translate_context* context);
+  Bexpression*
+  do_get_backend(Translate_context* context);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -14023,10 +13949,10 @@  Type_info_expression::do_type()
     }
 }
 
-// Return type information in GENERIC.
+// Return the backend representation for type information.
 
-tree
-Type_info_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Type_info_expression::do_get_backend(Translate_context* context)
 {
   Btype* btype = this->type_->get_backend(context->gogo());
   Gogo* gogo = context->gogo();
@@ -14051,7 +13977,7 @@  Type_info_expression::do_get_tree(Transl
   Bexpression* ret =
     gogo->backend()->integer_constant_expression(int_btype, cst);
   mpz_clear(cst);
-  return expr_to_tree(ret);
+  return ret;
 }
 
 // Dump ast representation for a type info expression.
@@ -14106,8 +14032,8 @@  class Slice_info_expression : public Exp
                                      this->location());
   }
 
-  tree
-  do_get_tree(Translate_context* context);
+  Bexpression*
+  do_get_backend(Translate_context* context);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -14141,27 +14067,24 @@  Slice_info_expression::do_type()
     }
 }
 
-// Return slice information in GENERIC.
+// Return the backend information for slice information.
 
-tree
-Slice_info_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Slice_info_expression::do_get_backend(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
-
-  Bexpression* bslice = tree_to_expr(this->slice_->get_tree(context));
-  Bexpression* ret;
+  Bexpression* bslice = this->slice_->get_backend(context);
   switch (this->slice_info_)
     {
     case SLICE_INFO_VALUE_POINTER:
     case SLICE_INFO_LENGTH:
     case SLICE_INFO_CAPACITY:
-      ret = gogo->backend()->struct_field_expression(bslice, this->slice_info_,
-                                                     this->location());
+      return gogo->backend()->struct_field_expression(bslice, this->slice_info_,
+						      this->location());
       break;
     default:
       go_unreachable();
     }
-  return expr_to_tree(ret);
 }
 
 // Dump ast representation for a type info expression.
@@ -14222,8 +14145,8 @@  class Slice_value_expression : public Ex
                                       this->location());
   }
 
-  tree
-  do_get_tree(Translate_context* context);
+  Bexpression*
+  do_get_backend(Translate_context* context);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -14249,19 +14172,17 @@  Slice_value_expression::do_traverse(Trav
   return TRAVERSE_CONTINUE;
 }
 
-tree
-Slice_value_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Slice_value_expression::do_get_backend(Translate_context* context)
 {
   std::vector<Bexpression*> vals(3);
-  vals[0] = tree_to_expr(this->valptr_->get_tree(context));
-  vals[1] = tree_to_expr(this->len_->get_tree(context));
-  vals[2] = tree_to_expr(this->cap_->get_tree(context));
+  vals[0] = this->valptr_->get_backend(context);
+  vals[1] = this->len_->get_backend(context);
+  vals[2] = this->cap_->get_backend(context);
 
   Gogo* gogo = context->gogo();
   Btype* btype = this->type_->get_backend(gogo);
-  Bexpression* ret =
-      gogo->backend()->constructor_expression(btype, vals, this->location());
-  return expr_to_tree(ret);
+  return gogo->backend()->constructor_expression(btype, vals, this->location());
 }
 
 void
@@ -14313,8 +14234,8 @@  class Interface_info_expression : public
                                          this->iface_info_, this->location());
   }
 
-  tree
-  do_get_tree(Translate_context* context);
+  Bexpression*
+  do_get_backend(Translate_context* context);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -14390,26 +14311,23 @@  Interface_info_expression::do_type()
     }
 }
 
-// Return interface information in GENERIC.
+// Return the backend representation for interface information.
 
-tree
-Interface_info_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Interface_info_expression::do_get_backend(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
-
-  Bexpression* biface = tree_to_expr(this->iface_->get_tree(context));
-  Bexpression* ret;
+  Bexpression* biface = this->iface_->get_backend(context);
   switch (this->iface_info_)
     {
     case INTERFACE_INFO_METHODS:
     case INTERFACE_INFO_OBJECT:
-      ret = gogo->backend()->struct_field_expression(biface, this->iface_info_,
-                                                     this->location());
+      return gogo->backend()->struct_field_expression(biface, this->iface_info_,
+						      this->location());
       break;
     default:
       go_unreachable();
     }
-  return expr_to_tree(ret);
 }
 
 // Dump ast representation for an interface info expression.
@@ -14472,8 +14390,8 @@  class Interface_value_expression : publi
                                           this->obj_->copy(), this->location());
   }
 
-  tree
-  do_get_tree(Translate_context* context);
+  Bexpression*
+  do_get_backend(Translate_context* context);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -14497,18 +14415,16 @@  Interface_value_expression::do_traverse(
   return TRAVERSE_CONTINUE;
 }
 
-tree
-Interface_value_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Interface_value_expression::do_get_backend(Translate_context* context)
 {
   std::vector<Bexpression*> vals(2);
-  vals[0] = tree_to_expr(this->first_field_->get_tree(context));
-  vals[1] = tree_to_expr(this->obj_->get_tree(context));
+  vals[0] = this->first_field_->get_backend(context);
+  vals[1] = this->obj_->get_backend(context);
 
   Gogo* gogo = context->gogo();
   Btype* btype = this->type_->get_backend(gogo);
-  Bexpression* ret =
-      gogo->backend()->constructor_expression(btype, vals, this->location());
-  return expr_to_tree(ret);
+  return gogo->backend()->constructor_expression(btype, vals, this->location());
 }
 
 void
@@ -14572,8 +14488,8 @@  class Interface_mtable_expression : publ
   do_is_addressable() const
   { return true; }
 
-  tree
-  do_get_tree(Translate_context* context);
+  Bexpression*
+  do_get_backend(Translate_context* context);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -14622,17 +14538,13 @@  Interface_mtable_expression::do_type()
   return this->method_table_type_;
 }
 
-tree
-Interface_mtable_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Interface_mtable_expression::do_get_backend(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
-  Bexpression* ret;
   Location loc = Linemap::predeclared_location();
   if (this->bvar_ != NULL)
-    {
-      ret = gogo->backend()->var_expression(this->bvar_, this->location());
-      return expr_to_tree(ret);
-    }
+    return gogo->backend()->var_expression(this->bvar_, this->location());
 
   const Typed_identifier_list* interface_methods = this->itype_->methods();
   go_assert(!interface_methods->empty());
@@ -14666,8 +14578,7 @@  Interface_mtable_expression::do_get_tree
       Btype* btype = this->type()->get_backend(gogo);
       this->bvar_ =
           gogo->backend()->immutable_struct_reference(mangled_name, btype, loc);
-      ret = gogo->backend()->var_expression(this->bvar_, this->location());
-      return expr_to_tree(ret);
+      return gogo->backend()->var_expression(this->bvar_, this->location());
     }
 
   // The first element is the type descriptor.
@@ -14707,15 +14618,14 @@  Interface_mtable_expression::do_get_tree
   Btype* btype = this->type()->get_backend(gogo);
   Expression* mtable = Expression::make_struct_composite_literal(this->type(),
                                                                  svals, loc);
-  Bexpression* ctor = tree_to_expr(mtable->get_tree(context));
+  Bexpression* ctor = mtable->get_backend(context);
 
   bool is_public = has_hidden_methods && this->type_->named_type() != NULL;
   this->bvar_ = gogo->backend()->immutable_struct(mangled_name, false,
 						  !is_public, btype, loc);
   gogo->backend()->immutable_struct_set_init(this->bvar_, mangled_name, false,
                                              !is_public, btype, loc, ctor);
-  ret = gogo->backend()->var_expression(this->bvar_, loc);
-  return expr_to_tree(ret);
+  return gogo->backend()->var_expression(this->bvar_, loc);
 }
 
 void
@@ -14766,8 +14676,8 @@  class Struct_field_offset_expression : p
   do_copy()
   { return this; }
 
-  tree
-  do_get_tree(Translate_context* context);
+  Bexpression*
+  do_get_backend(Translate_context* context);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -14779,10 +14689,10 @@  class Struct_field_offset_expression : p
   const Struct_field* field_;
 };
 
-// Return a struct field offset in GENERIC.
+// Return the backend representation for a struct field offset.
 
-tree
-Struct_field_offset_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Struct_field_offset_expression::do_get_backend(Translate_context* context)
 {
   const Struct_field_list* fields = this->type_->fields();
   Struct_field_list::const_iterator p;
@@ -14804,7 +14714,7 @@  Struct_field_offset_expression::do_get_t
   Expression* ret = Expression::make_integer(&offsetval, uptr_type,
 					     Linemap::predeclared_location());
   mpz_clear(offsetval);
-  return ret->get_tree(context);
+  return ret->get_backend(context);
 }
 
 // Dump ast representation for a struct field offset expression.
@@ -14854,12 +14764,11 @@  class Map_descriptor_expression : public
   do_copy()
   { return this; }
 
-  tree
-  do_get_tree(Translate_context* context)
+  Bexpression*
+  do_get_backend(Translate_context* context)
   {
-    Bexpression* ret = this->type_->map_descriptor_pointer(context->gogo(),
-                                                           this->location());
-    return expr_to_tree(ret);
+    return this->type_->map_descriptor_pointer(context->gogo(),
+					       this->location());
   }
 
   void
@@ -14912,11 +14821,9 @@  class Label_addr_expression : public Exp
   do_copy()
   { return new Label_addr_expression(this->label_, this->location()); }
 
-  tree
-  do_get_tree(Translate_context* context)
-  {
-    return expr_to_tree(this->label_->get_addr(context, this->location()));
-  }
+  Bexpression*
+  do_get_backend(Translate_context* context)
+  { return this->label_->get_addr(context, this->location()); }
 
   void
   do_dump_expression(Ast_dump_context* ast_dump_context) const
@@ -14963,8 +14870,8 @@  class Conditional_expression : public Ex
                                       this->else_->copy(), this->location());
   }
 
-  tree
-  do_get_tree(Translate_context* context);
+  Bexpression*
+  do_get_backend(Translate_context* context);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -15019,18 +14926,16 @@  Conditional_expression::do_determine_typ
 
 // Get the backend representation of a conditional expression.
 
-tree
-Conditional_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Conditional_expression::do_get_backend(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
   Btype* result_btype = this->type()->get_backend(gogo);
-  Bexpression* cond = tree_to_expr(this->cond_->get_tree(context));
-  Bexpression* then = tree_to_expr(this->then_->get_tree(context));
-  Bexpression* belse = tree_to_expr(this->else_->get_tree(context));
-  Bexpression* ret =
-      gogo->backend()->conditional_expression(result_btype, cond, then, belse,
-                                              this->location());
-  return expr_to_tree(ret);
+  Bexpression* cond = this->cond_->get_backend(context);
+  Bexpression* then = this->then_->get_backend(context);
+  Bexpression* belse = this->else_->get_backend(context);
+  return gogo->backend()->conditional_expression(result_btype, cond, then,
+						 belse, this->location());
 }
 
 // Dump ast representation of a conditional expression.
@@ -15083,8 +14988,8 @@  class Compound_expression : public Expre
                                    this->location());
   }
 
-  tree
-  do_get_tree(Translate_context* context);
+  Bexpression*
+  do_get_backend(Translate_context* context);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -15126,16 +15031,15 @@  Compound_expression::do_determine_type(c
 
 // Get the backend representation of a compound expression.
 
-tree
-Compound_expression::do_get_tree(Translate_context* context)
+Bexpression*
+Compound_expression::do_get_backend(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
-  Bexpression* binit = tree_to_expr(this->init_->get_tree(context));
+  Bexpression* binit = this->init_->get_backend(context);
   Bstatement* init_stmt = gogo->backend()->expression_statement(binit);
-  Bexpression* bexpr = tree_to_expr(this->expr_->get_tree(context));
-  Bexpression* ret = gogo->backend()->compound_expression(init_stmt, bexpr,
-                                                          this->location());
-  return expr_to_tree(ret);
+  Bexpression* bexpr = this->expr_->get_backend(context);
+  return gogo->backend()->compound_expression(init_stmt, bexpr,
+					      this->location());
 }
 
 // Dump ast representation of a conditional expression.
Index: gcc/go/gofrontend/expressions.h
===================================================================
--- gcc/go/gofrontend/expressions.h	(revision 210088)
+++ gcc/go/gofrontend/expressions.h	(working copy)
@@ -747,9 +747,9 @@  class Expression
     return this->do_must_eval_subexpressions_in_order(skip);
   }
 
-  // Return the tree for this expression.
-  tree
-  get_tree(Translate_context*);
+  // Return the backend representation for this expression.
+  Bexpression*
+  get_backend(Translate_context*);
 
   // Return an expression handling any conversions which must be done during
   // assignment.
@@ -883,9 +883,9 @@  class Expression
   do_must_eval_subexpressions_in_order(int* /* skip */) const
   { return false; }
 
-  // Child class implements conversion to tree.
-  virtual tree
-  do_get_tree(Translate_context*) = 0;
+  // Child class implements conversion to backend representation.
+  virtual Bexpression*
+  do_get_backend(Translate_context*) = 0;
 
   // Child class implements export.
   virtual void
@@ -1068,8 +1068,8 @@  class Parser_expression : public Express
   do_check_types(Gogo*)
   { go_unreachable(); }
 
-  tree
-  do_get_tree(Translate_context*)
+  Bexpression*
+  do_get_backend(Translate_context*)
   { go_unreachable(); }
 };
 
@@ -1109,8 +1109,8 @@  class Var_expression : public Expression
   void
   do_address_taken(bool);
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -1161,8 +1161,8 @@  class Temporary_reference_expression : p
   void
   do_address_taken(bool);
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -1221,8 +1221,8 @@  class Set_and_use_temporary_expression :
   void
   do_address_taken(bool);
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -1277,8 +1277,8 @@  class String_expression : public Express
   do_copy()
   { return this; }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   // Write string literal to a string dump.
   static void
@@ -1410,8 +1410,8 @@  class Unary_expression : public Expressi
   do_is_addressable() const
   { return this->op_ == OPERATOR_MULT; }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_export(Export*) const;
@@ -1534,8 +1534,8 @@  class Binary_expression : public Express
 				   this->right_->copy(), this->location());
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_export(Export*) const;
@@ -1715,8 +1715,8 @@  class Call_expression : public Expressio
   bool
   do_must_eval_in_order() const;
 
-  virtual tree
-  do_get_tree(Translate_context*);
+  virtual Bexpression*
+  do_get_backend(Translate_context*);
 
   virtual bool
   do_is_recover_call() const;
@@ -1834,8 +1834,8 @@  class Func_expression : public Expressio
 					   this->location());
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -1881,8 +1881,8 @@  class Func_descriptor_expression : publi
   do_is_addressable() const
   { return true; }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context* context) const;
@@ -2124,8 +2124,8 @@  class Map_index_expression : public Expr
 
   // A map index expression is an lvalue but it is not addressable.
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -2210,8 +2210,8 @@  class Bound_method_expression : public E
 				       this->function_, this->location());
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -2313,8 +2313,8 @@  class Field_reference_expression : publi
   do_issue_nil_check()
   { this->expr_->issue_nil_check(); }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -2392,8 +2392,8 @@  class Interface_field_reference_expressi
 						      this->location());
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -2458,8 +2458,8 @@  class Type_guard_expression : public Exp
 				     this->location());
   }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -2518,8 +2518,8 @@  class Receive_expression : public Expres
   do_must_eval_in_order() const
   { return true; }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bexpression*
+  do_get_backend(Translate_context*);
 
   void
   do_dump_expression(Ast_dump_context*) const;
Index: gcc/go/gofrontend/statements.cc
===================================================================
--- gcc/go/gofrontend/statements.cc	(revision 209819)
+++ gcc/go/gofrontend/statements.cc	(working copy)
@@ -291,12 +291,12 @@  Variable_declaration_statement::do_get_b
     {
       Expression* e = Expression::make_temporary_reference(temp, loc);
       e = Expression::make_unary(OPERATOR_MULT, e, loc);
-      Bexpression* be = tree_to_expr(e->get_tree(context));
+      Bexpression* be = e->get_backend(context);
       set = context->backend()->assignment_statement(be, binit, loc);
     }
 
   Expression* ref = Expression::make_temporary_reference(temp, loc);
-  Bexpression* bref = tree_to_expr(ref->get_tree(context));
+  Bexpression* bref = ref->get_backend(context);
   Bstatement* sinit = context->backend()->init_statement(bvar, bref);
 
   std::vector<Bstatement*> stats;
@@ -443,13 +443,13 @@  Temporary_statement::do_get_backend(Tran
   if (this->init_ == NULL)
     binit = NULL;
   else if (this->type_ == NULL)
-    binit = tree_to_expr(this->init_->get_tree(context));
+    binit = this->init_->get_backend(context);
   else
     {
       Expression* init = Expression::make_cast(this->type_, this->init_,
 					       this->location());
       context->gogo()->lower_expression(context->function(), NULL, &init);
-      binit = tree_to_expr(init->get_tree(context));
+      binit = init->get_backend(context);
     }
 
   Bstatement* statement;
@@ -633,18 +633,16 @@  Assignment_statement::do_get_backend(Tra
 {
   if (this->lhs_->is_sink_expression())
     {
-      tree rhs_tree = this->rhs_->get_tree(context);
-      return context->backend()->expression_statement(tree_to_expr(rhs_tree));
+      Bexpression* rhs = this->rhs_->get_backend(context);
+      return context->backend()->expression_statement(rhs);
     }
 
-  tree lhs_tree = this->lhs_->get_tree(context);
-  Expression* rhs =
+  Bexpression* lhs = this->lhs_->get_backend(context);
+  Expression* conv =
       Expression::convert_for_assignment(context->gogo(), this->lhs_->type(),
                                          this->rhs_, this->location());
-  tree rhs_tree = rhs->get_tree(context);
-  return context->backend()->assignment_statement(tree_to_expr(lhs_tree),
-						  tree_to_expr(rhs_tree),
-						  this->location());
+  Bexpression* rhs = conv->get_backend(context);
+  return context->backend()->assignment_statement(lhs, rhs, this->location());
 }
 
 // Dump the AST representation for an assignment statement.
@@ -1748,8 +1746,8 @@  Expression_statement::do_may_fall_throug
 Bstatement*
 Expression_statement::do_get_backend(Translate_context* context)
 {
-  tree expr_tree = this->expr_->get_tree(context);
-  return context->backend()->expression_statement(tree_to_expr(expr_tree));
+  Bexpression* bexpr = this->expr_->get_backend(context);
+  return context->backend()->expression_statement(bexpr);
 }
 
 // Dump the AST representation for an expression statement
@@ -2537,9 +2535,8 @@  Go_statement::do_get_backend(Translate_c
 
   Expression* call = Runtime::make_call(Runtime::GO, this->location(), 2,
 					fn, arg);
-  tree call_tree = call->get_tree(context);
-  Bexpression* call_bexpr = tree_to_expr(call_tree);
-  return context->backend()->expression_statement(call_bexpr);
+  Bexpression* bcall = call->get_backend(context);
+  return context->backend()->expression_statement(bcall);
 }
 
 // Dump the AST representation for go statement.
@@ -2576,9 +2573,8 @@  Defer_statement::do_get_backend(Translat
 
   Expression* call = Runtime::make_call(Runtime::DEFER, loc, 3,
 					ds, fn, arg);
-  tree call_tree = call->get_tree(context);
-  Bexpression* call_bexpr = tree_to_expr(call_tree);
-  return context->backend()->expression_statement(call_bexpr);
+  Bexpression* bcall = call->get_backend(context);
+  return context->backend()->expression_statement(bcall);
 }
 
 // Dump the AST representation for defer statement.
@@ -2785,7 +2781,7 @@  Return_statement::do_get_backend(Transla
 	   p++)
 	{
 	  Expression* vr = Expression::make_var_reference(*p, loc);
-	  retvals.push_back(tree_to_expr(vr->get_tree(context)));
+	  retvals.push_back(vr->get_backend(context));
 	}
     }
 
@@ -3201,14 +3197,13 @@  If_statement::do_get_backend(Translate_c
 {
   go_assert(this->cond_->type()->is_boolean_type()
 	     || this->cond_->type()->is_error());
-  tree cond_tree = this->cond_->get_tree(context);
-  Bexpression* cond_expr = tree_to_expr(cond_tree);
+  Bexpression* cond = this->cond_->get_backend(context);
   Bblock* then_block = this->then_block_->get_backend(context);
   Bblock* else_block = (this->else_block_ == NULL
 			? NULL
 			: this->else_block_->get_backend(context));
-  return context->backend()->if_statement(cond_expr, then_block,
-					  else_block, this->location());
+  return context->backend()->if_statement(cond, then_block, else_block,
+					  this->location());
 }
 
 // Dump the AST representation for an if statement
@@ -3485,10 +3480,7 @@  Case_clauses::Case_clause::get_backend(T
 	      error_at(this->location_, "duplicate case in switch");
 	      e = Expression::make_error(this->location_);
 	    }
-
-	  tree case_tree = e->get_tree(context);
-	  Bexpression* case_expr = tree_to_expr(case_tree);
-	  cases->push_back(case_expr);
+	  cases->push_back(e->get_backend(context));
 	}
     }
 
@@ -3783,8 +3775,7 @@  Constant_switch_statement::do_check_type
 Bstatement*
 Constant_switch_statement::do_get_backend(Translate_context* context)
 {
-  tree switch_val_tree = this->val_->get_tree(context);
-  Bexpression* switch_val_expr = tree_to_expr(switch_val_tree);
+  Bexpression* switch_val_expr = this->val_->get_backend(context);
 
   Unnamed_label* break_label = this->break_label_;
   if (break_label == NULL)
@@ -4519,7 +4510,7 @@  Send_statement::do_get_backend(Translate
   Expression* call = Runtime::make_call(code, loc, 3, td, this->channel_, val);
 
   context->gogo()->lower_expression(context->function(), NULL, &call);
-  Bexpression* bcall = tree_to_expr(call->get_tree(context));
+  Bexpression* bcall = call->get_backend(context);
   Bstatement* s = context->backend()->expression_statement(bcall);
 
   if (btemp == NULL)
@@ -4948,7 +4939,7 @@  Select_clauses::get_backend(Translate_co
       Expression* index_expr = Expression::make_integer(&ival, int32_type,
 							location);
       mpz_clear(ival);
-      cases[i].push_back(tree_to_expr(index_expr->get_tree(context)));
+      cases[i].push_back(index_expr->get_backend(context));
 
       Bstatement* s = p->get_statements_backend(context);
       Location gloc = (p->statements() == NULL
@@ -4966,7 +4957,7 @@  Select_clauses::get_backend(Translate_co
   Expression* call = Runtime::make_call(Runtime::SELECTGO, location, 1,
 					selref);
   context->gogo()->lower_expression(context->function(), NULL, &call);
-  Bexpression* bcall = tree_to_expr(call->get_tree(context));
+  Bexpression* bcall = call->get_backend(context);
 
   if (count == 0)
     return context->backend()->expression_statement(bcall);
Index: gcc/go/gofrontend/backend.h
===================================================================
--- gcc/go/gofrontend/backend.h	(revision 210088)
+++ gcc/go/gofrontend/backend.h	(working copy)
@@ -247,6 +247,10 @@  class Backend
   virtual Bexpression*
   error_expression() = 0;
 
+  // Create a nil pointer expression.
+  virtual Bexpression*
+  nil_pointer_expression() = 0;
+
   // Create a reference to a variable.
   virtual Bexpression*
   var_expression(Bvariable* var, Location) = 0;
@@ -281,6 +285,10 @@  class Backend
   virtual Bexpression*
   string_constant_expression(const std::string& val) = 0;
 
+  // Return an expression for the boolean value VAL.
+  virtual Bexpression*
+  boolean_constant_expression(bool val) = 0;
+
   // Return an expression for the real part of BCOMPLEX.
   virtual Bexpression*
   real_part_expression(Bexpression* bcomplex, Location) = 0;
@@ -687,19 +695,4 @@  class Backend
 
 extern Backend* go_get_backend();
 
-// FIXME: Temporary helper functions while converting to new backend
-// interface.
-
-extern Btype* tree_to_type(tree);
-extern Bexpression* tree_to_expr(tree);
-extern Bstatement* tree_to_stat(tree);
-extern Bfunction* tree_to_function(tree);
-extern Bblock* tree_to_block(tree);
-extern tree type_to_tree(Btype*);
-extern tree expr_to_tree(Bexpression*);
-extern tree stat_to_tree(Bstatement*);
-extern tree block_to_tree(Bblock*);
-extern tree var_to_tree(Bvariable*);
-extern tree function_to_tree(Bfunction*);
-
 #endif // !defined(GO_BACKEND_H)
Index: gcc/go/gofrontend/gogo.h
===================================================================
--- gcc/go/gofrontend/gogo.h	(revision 210109)
+++ gcc/go/gofrontend/gogo.h	(working copy)
@@ -1096,7 +1096,7 @@  class Function
   Bstatement*
   return_value(Gogo*, Named_object*, Location) const;
 
-  // Get a tree for the variable holding the defer stack.
+  // Get an expression for the variable holding the defer stack.
   Expression*
   defer_stack(Location);
 
Index: gcc/go/gofrontend/gogo.cc
===================================================================
--- gcc/go/gofrontend/gogo.cc	(revision 210087)
+++ gcc/go/gofrontend/gogo.cc	(working copy)
@@ -729,7 +729,7 @@  Gogo::register_gc_vars(const std::vector
                                                   builtin_loc, 1, root_addr);
 
   Translate_context context(this, NULL, NULL, NULL);
-  Bexpression* bcall = tree_to_expr(register_roots->get_tree(&context));
+  Bexpression* bcall = register_roots->get_backend(&context);
   init_stmts.push_back(this->backend()->expression_statement(bcall));
 }
 
@@ -4065,8 +4065,8 @@  Build_method_tables::type(Type* type)
 	      if ((*p)->implements_interface(Type::make_pointer_type(nt),
 					     NULL))
 		{
-		  nt->interface_method_table(*p, false)->get_tree(&context);
-                  nt->interface_method_table(*p, true)->get_tree(&context);
+		  nt->interface_method_table(*p, false)->get_backend(&context);
+                  nt->interface_method_table(*p, true)->get_backend(&context);
 		}
 	    }
 	  else
@@ -4074,8 +4074,8 @@  Build_method_tables::type(Type* type)
 	      if ((*p)->implements_interface(Type::make_pointer_type(st),
 					     NULL))
 		{
-		  st->interface_method_table(*p, false)->get_tree(&context);
-		  st->interface_method_table(*p, true)->get_tree(&context);
+		  st->interface_method_table(*p, false)->get_backend(&context);
+		  st->interface_method_table(*p, true)->get_backend(&context);
 		}
 	    }
 	}
@@ -4916,7 +4916,7 @@  Function_declaration::build_backend_desc
   if (this->descriptor_ != NULL)
     {
       Translate_context context(gogo, NULL, NULL, NULL);
-      this->descriptor_->get_tree(&context);
+      this->descriptor_->get_backend(&context);
     }
 }
 
@@ -4975,7 +4975,7 @@  Function::build(Gogo* gogo, Named_object
 	      parm_ref = Expression::make_unary(OPERATOR_MULT, parm_ref, loc);
 	      if ((*p)->var_value()->is_in_heap())
 		parm_ref = Expression::make_heap_expression(parm_ref, loc);
-              var_inits.push_back(tree_to_expr(parm_ref->get_tree(&context)));
+              var_inits.push_back(parm_ref->get_backend(&context));
 	    }
 	  else if ((*p)->var_value()->is_in_heap())
 	    {
@@ -4992,7 +4992,7 @@  Function::build(Gogo* gogo, Named_object
 	      Expression* var_ref =
 		  Expression::make_var_reference(parm_no, loc);
 	      var_ref = Expression::make_heap_expression(var_ref, loc);
-              var_inits.push_back(tree_to_expr(var_ref->get_tree(&context)));
+              var_inits.push_back(var_ref->get_backend(&context));
 	    }
           param_vars.push_back(parm_bvar);
 	}
@@ -5008,10 +5008,8 @@  Function::build(Gogo* gogo, Named_object
 	      init = gogo->backend()->zero_expression(btype);
 	    }
 	  else
-            {
-              Expression* alloc = Expression::make_allocation(type, loc);
-              init = tree_to_expr(alloc->get_tree(&context));
-            }
+	    init = Expression::make_allocation(type,
+					       loc)->get_backend(&context);
 
           vars.push_back(bvar);
           var_inits.push_back(init);
@@ -5034,7 +5032,7 @@  Function::build(Gogo* gogo, Named_object
 
       Expression* closure =
           Runtime::make_call(Runtime::GET_CLOSURE, this->location_, 0);
-      var_inits.push_back(tree_to_expr(closure->get_tree(&context)));
+      var_inits.push_back(closure->get_backend(&context));
     }
 
   if (this->block_ != NULL)
@@ -5115,7 +5113,7 @@  Function::build(Gogo* gogo, Named_object
   if (this->descriptor_ != NULL)
     {
       Translate_context context(gogo, NULL, NULL, NULL);
-      this->descriptor_->get_tree(&context);
+      this->descriptor_->get_backend(&context);
     }
 }
 
@@ -5138,7 +5136,7 @@  Function::build_defer_wrapper(Gogo* gogo
   Expression* call = Runtime::make_call(Runtime::CHECK_DEFER, end_loc, 1,
 					this->defer_stack(end_loc));
   Translate_context context(gogo, named_function, NULL, NULL);
-  Bexpression* defer = tree_to_expr(call->get_tree(&context));
+  Bexpression* defer = call->get_backend(&context);
   stmts.push_back(gogo->backend()->expression_statement(defer));
 
   Bstatement* ret_bstmt = this->return_value(gogo, named_function, end_loc);
@@ -5150,11 +5148,11 @@  Function::build_defer_wrapper(Gogo* gogo
 
   call = Runtime::make_call(Runtime::CHECK_DEFER, end_loc, 1,
                             this->defer_stack(end_loc));
-  defer = tree_to_expr(call->get_tree(&context));
+  defer = call->get_backend(&context);
 
   call = Runtime::make_call(Runtime::UNDEFER, end_loc, 1,
         		    this->defer_stack(end_loc));
-  Bexpression* undefer = tree_to_expr(call->get_tree(&context));
+  Bexpression* undefer = call->get_backend(&context);
   Bstatement* function_defer =
       gogo->backend()->function_defer_statement(this->fndecl_, undefer, defer,
                                                 end_loc);
@@ -5170,13 +5168,12 @@  Function::build_defer_wrapper(Gogo* gogo
       // variable to true if we are returning from this function.
 
       ret_bstmt = this->return_value(gogo, named_function, end_loc);
-      Bexpression* nil =
-          tree_to_expr(Expression::make_nil(end_loc)->get_tree(&context));
+      Bexpression* nil = Expression::make_nil(end_loc)->get_backend(&context);
       Bexpression* ret =
           gogo->backend()->compound_expression(ret_bstmt, nil, end_loc);
       Expression* ref =
 	Expression::make_temporary_reference(this->defer_stack_, end_loc);
-      Bexpression* bref = tree_to_expr(ref->get_tree(&context));
+      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));
@@ -5982,7 +5979,7 @@  Variable::get_init(Gogo* gogo, Named_obj
     {
       Translate_context context(gogo, function, NULL, NULL);
       Expression* init = Expression::make_cast(this->type(), this->init_, loc);
-      return tree_to_expr(init->get_tree(&context));
+      return init->get_backend(&context);
     }
 }
 
@@ -6008,8 +6005,7 @@  Variable::get_init_block(Gogo* gogo, Nam
     {
       if (var_decl == NULL)
         {
-          Bexpression* init_bexpr =
-              tree_to_expr(this->init_->get_tree(&context));
+          Bexpression* init_bexpr = this->init_->get_backend(&context);
           decl_init = gogo->backend()->expression_statement(init_bexpr);
         }
       else
@@ -6017,7 +6013,7 @@  Variable::get_init_block(Gogo* gogo, Nam
           Location loc = this->location();
           Expression* val_expr =
               Expression::make_cast(this->type(), this->init_, loc);
-          Bexpression* val = tree_to_expr(val_expr->get_tree(&context));
+          Bexpression* val = val_expr->get_backend(&context);
           Bexpression* var_ref = gogo->backend()->var_expression(var_decl, loc);
           decl_init = gogo->backend()->assignment_statement(var_ref, val, loc);
 	}
@@ -6241,8 +6237,7 @@  Named_constant::get_backend(Gogo* gogo,
       Location loc = this->location();
 
       Expression* const_ref = Expression::make_const_reference(const_no, loc);
-      Bexpression* const_decl =
-	tree_to_expr(const_ref->get_tree(&subcontext));
+      Bexpression* const_decl = const_ref->get_backend(&subcontext);
       if (type != NULL && type->is_numeric_type())
 	{
 	  Btype* btype = type->get_backend(gogo);
Index: gcc/go/gofrontend/types.cc
===================================================================
--- gcc/go/gofrontend/types.cc	(revision 210096)
+++ gcc/go/gofrontend/types.cc	(working copy)
@@ -6,12 +6,6 @@ 
 
 #include "go-system.h"
 
-#include "toplev.h"
-#include "intl.h"
-#include "tree.h"
-#include "real.h"
-#include "convert.h"
-
 #include "go-c.h"
 #include "gogo.h"
 #include "operator.h"
@@ -897,7 +891,7 @@  Type::hash_string(const std::string& s,
 
 Type::Type_btypes Type::type_btypes;
 
-// Return a tree representing this type.
+// Return the backend representation for this type.
 
 Btype*
 Type::get_backend(Gogo* gogo)
@@ -952,7 +946,7 @@  Type::get_backend(Gogo* gogo)
       // We have already created a backend representation for this
       // type.  This can happen when an unnamed type is defined using
       // a named type which in turns uses an identical unnamed type.
-      // Use the tree we created earlier and ignore the one we just
+      // Use the representation we created earlier and ignore the one we just
       // built.
       if (this->btype_ == bt)
 	this->btype_ = ins.first->second.btype;
@@ -1301,7 +1295,7 @@  Type::make_type_descriptor_var(Gogo* gog
 
   Translate_context context(gogo, NULL, NULL, NULL);
   context.set_is_const();
-  Bexpression* binitializer = tree_to_expr(initializer->get_tree(&context));
+  Bexpression* binitializer = initializer->get_backend(&context);
 
   gogo->backend()->immutable_struct_set_init(this->type_descriptor_var_,
 					     var_name, false, is_common,
@@ -4936,7 +4930,7 @@  get_backend_struct_fields(Gogo* gogo, co
   go_assert(i == fields->size());
 }
 
-// Get the tree for a struct type.
+// Get the backend representation for a struct type.
 
 Btype*
 Struct_type::do_get_backend(Gogo* gogo)
@@ -5877,9 +5871,9 @@  get_backend_slice_fields(Gogo* gogo, Arr
   p->location = ploc;
 }
 
-// Get a tree for the type of this array.  A fixed array is simply
-// represented as ARRAY_TYPE with the appropriate index--i.e., it is
-// just like an array in C.  A slice is a struct with three
+// Get the backend representation for the type of this array.  A fixed array is
+// simply represented as ARRAY_TYPE with the appropriate index--i.e., it is
+// just like an array in C.  An open array is a struct with three
 // fields: a data pointer, the length, and the capacity.
 
 Btype*
@@ -5943,7 +5937,7 @@  Array_type::get_backend_length(Gogo* gog
 	  // Make up a translation context for the array length
 	  // expression.  FIXME: This won't work in general.
 	  Translate_context context(gogo, NULL, NULL, NULL);
-	  this->blength_ = tree_to_expr(this->length_->get_tree(&context));
+	  this->blength_ = this->length_->get_backend(&context);
 
 	  Btype* ibtype = Type::lookup_integer_type("int")->get_backend(gogo);
 	  this->blength_ =
@@ -6466,7 +6460,7 @@  Map_type::map_descriptor(Gogo* gogo)
 
   Translate_context context(gogo, NULL, NULL, NULL);
   context.set_is_const();
-  Bexpression* binitializer = tree_to_expr(initializer->get_tree(&context));
+  Bexpression* binitializer = initializer->get_backend(&context);
 
   gogo->backend()->immutable_struct_set_init(bvar, mangled_name, false, true,
 					     map_descriptor_btype, bloc,
@@ -6581,8 +6575,8 @@  Channel_type::is_identical(const Channel
 	  && this->may_receive_ == t->may_receive_);
 }
 
-// Return the tree for a channel type.  A channel is a pointer to a
-// __go_channel struct.  The __go_channel struct is defined in
+// Return the backend representation for a channel type.  A channel is a pointer
+// to a __go_channel struct.  The __go_channel struct is defined in
 // libgo/runtime/channel.h.
 
 Btype*
@@ -7364,8 +7358,8 @@  get_backend_interface_fields(Gogo* gogo,
   (*bfields)[1].location = Linemap::predeclared_location();
 }
 
-// Return a tree for an interface type.  An interface is a pointer to
-// a struct.  The struct has three fields.  The first field is a
+// Return the backend representation for an interface type.  An interface is a
+// pointer to a struct.  The struct has three fields.  The first field is a
 // pointer to the type descriptor for the dynamic type of the object.
 // The second field is a pointer to a table of methods for the
 // interface to be used with the object.  The third field is the value
@@ -8416,7 +8410,7 @@  Named_type::convert(Gogo* gogo)
   this->verify();
 
   // Convert all the dependencies.  If they refer indirectly back to
-  // this type, they will pick up the intermediate tree we just
+  // this type, they will pick up the intermediate representation we just
   // created.
   for (std::vector<Named_type*>::const_iterator p = this->dependencies_.begin();
        p != this->dependencies_.end();
@@ -8612,7 +8606,7 @@  Named_type::create_placeholder(Gogo* gog
     }
 }
 
-// Get a tree for a named type.
+// Get the backend representation for a named type.
 
 Btype*
 Named_type::do_get_backend(Gogo* gogo)
@@ -8648,7 +8642,7 @@  Named_type::do_get_backend(Gogo* gogo)
 
   go_assert(bt != NULL);
 
-  // Complete the tree.
+  // Complete the backend representation.
   Type* base = this->type_->base();
   Btype* bt1;
   switch (base->classification())
Index: gcc/go/gofrontend/types.h
===================================================================
--- gcc/go/gofrontend/types.h	(revision 210096)
+++ gcc/go/gofrontend/types.h	(working copy)
@@ -1168,9 +1168,6 @@  class Type
   method_constructor(Gogo*, Type* method_type, const std::string& name,
 		     const Method*, bool only_value_methods) const;
 
-  static tree
-  build_receive_return_type(tree type);
-
   // Add all methods for TYPE to the list of methods for THIS.
   static void
   add_methods_for_type(const Type* type, const Method::Field_indexes*,
@@ -2755,9 +2752,9 @@  class Interface_type : public Type
 };
 
 // The value we keep for a named type.  This lets us get the right
-// name when we convert to trees.  Note that we don't actually keep
+// name when we convert to backend.  Note that we don't actually keep
 // the name here; the name is in the Named_object which points to
-// this.  This object exists to hold a unique tree which represents
+// this.  This object exists to hold a unique backend representation for
 // the type.
 
 class Named_type : public Type
Index: gcc/go/go-gcc.cc
===================================================================
--- gcc/go/go-gcc.cc	(revision 210088)
+++ gcc/go/go-gcc.cc	(working copy)
@@ -226,6 +226,10 @@  class Gcc_backend : public Backend
   { return this->make_expression(error_mark_node); }
 
   Bexpression*
+  nil_pointer_expression()
+  { return this->make_expression(null_pointer_node); }
+
+  Bexpression*
   var_expression(Bvariable* var, Location);
 
   Bexpression*
@@ -248,6 +252,9 @@  class Gcc_backend : public Backend
   string_constant_expression(const std::string& val);
 
   Bexpression*
+  boolean_constant_expression(bool val);
+
+  Bexpression*
   real_part_expression(Bexpression* bcomplex, Location);
 
   Bexpression*
@@ -1130,7 +1137,7 @@  Gcc_backend::zero_expression(Btype* btyp
     ret = error_mark_node;
   else
     ret = build_zero_cst(t);
-  return tree_to_expr(ret);
+  return this->make_expression(ret);
 }
 
 // An expression that references a variable.
@@ -1141,7 +1148,7 @@  Gcc_backend::var_expression(Bvariable* v
   tree ret = var->get_tree();
   if (ret == error_mark_node)
     return this->error_expression();
-  return tree_to_expr(ret);
+  return this->make_expression(ret);
 }
 
 // An expression that indirectly references an expression.
@@ -1202,7 +1209,7 @@  Gcc_backend::integer_constant_expression
     return this->error_expression();
 
   tree ret = double_int_to_tree(t, mpz_get_double_int(t, val, true));
-  return tree_to_expr(ret);
+  return this->make_expression(ret);
 }
 
 // Return a typed value as a constant floating-point number.
@@ -1220,7 +1227,7 @@  Gcc_backend::float_constant_expression(B
   REAL_VALUE_TYPE r2;
   real_convert(&r2, TYPE_MODE(t), &r1);
   ret = build_real(t, r2);
-  return tree_to_expr(ret);
+  return this->make_expression(ret);
 }
 
 // Return a typed real and imaginary value as a constant complex number.
@@ -1245,7 +1252,7 @@  Gcc_backend::complex_constant_expression
 
   ret = build_complex(t, build_real(TREE_TYPE(t), r2),
                       build_real(TREE_TYPE(t), r4));
-  return tree_to_expr(ret);
+  return this->make_expression(ret);
 }
 
 // Make a constant string expression.
@@ -1265,6 +1272,15 @@  Gcc_backend::string_constant_expression(
   return this->make_expression(string_val);
 }
 
+// Make a constant boolean expression.
+
+Bexpression*
+Gcc_backend::boolean_constant_expression(bool val)
+{
+  tree bool_cst = val ? boolean_true_node : boolean_false_node;
+  return this->make_expression(bool_cst);
+}
+
 // Return the real part of a complex expression.
 
 Bexpression*
@@ -1408,7 +1424,7 @@  Gcc_backend::struct_field_expression(Bex
                              NULL_TREE);
   if (TREE_CONSTANT(struct_tree))
     TREE_CONSTANT(ret) = 1;
-  return tree_to_expr(ret);
+  return this->make_expression(ret);
 }
 
 // Return an expression that executes BSTAT before BEXPR.
@@ -2924,73 +2940,3 @@  go_get_backend()
 {
   return new Gcc_backend();
 }
-
-// FIXME: Temporary functions while converting to the new backend
-// interface.
-
-Btype*
-tree_to_type(tree t)
-{
-  return new Btype(t);
-}
-
-Bexpression*
-tree_to_expr(tree t)
-{
-  return new Bexpression(t);
-}
-
-Bstatement*
-tree_to_stat(tree t)
-{
-  return new Bstatement(t);
-}
-
-Bfunction*
-tree_to_function(tree t)
-{
-  return new Bfunction(t);
-}
-
-Bblock*
-tree_to_block(tree t)
-{
-  gcc_assert(TREE_CODE(t) == BIND_EXPR);
-  return new Bblock(t);
-}
-
-tree
-type_to_tree(Btype* bt)
-{
-  return bt->get_tree();
-}
-
-tree
-expr_to_tree(Bexpression* be)
-{
-  return be->get_tree();
-}
-
-tree
-stat_to_tree(Bstatement* bs)
-{
-  return bs->get_tree();
-}
-
-tree
-block_to_tree(Bblock* bb)
-{
-  return bb->get_tree();
-}
-
-tree
-var_to_tree(Bvariable* bv)
-{
-  return bv->get_tree();
-}
-
-tree
-function_to_tree(Bfunction* bf)
-{
-  return bf->get_tree();
-}