diff mbox

Go patch committed: Use backend types for all type conversions

Message ID mcrsjsrqsgb.fsf@coign.corp.google.com
State New
Headers show

Commit Message

Ian Lance Taylor May 7, 2011, 12:12 a.m. UTC
This mechanical patch uses the backend type structure, rather than tree,
for all type conversions.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff mbox

Patch

diff -r 24bf02cfb81b go/expressions.cc
--- a/go/expressions.cc	Fri May 06 13:04:22 2011 -0700
+++ b/go/expressions.cc	Fri May 06 17:01:19 2011 -0700
@@ -214,7 +214,7 @@ 
 
   Gogo* gogo = context->gogo();
 
-  tree lhs_type_tree = lhs_type->get_tree(gogo);
+  tree lhs_type_tree = type_to_tree(lhs_type->get_backend(gogo));
   if (lhs_type_tree == error_mark_node)
     return error_mark_node;
 
@@ -323,7 +323,7 @@ 
   // This should have been checked already.
   go_assert(lhs_interface_type->implements_interface(rhs_type, NULL));
 
-  tree lhs_type_tree = lhs_type->get_tree(gogo);
+  tree lhs_type_tree = type_to_tree(lhs_type->get_backend(gogo));
   if (lhs_type_tree == error_mark_node)
     return error_mark_node;
 
@@ -456,7 +456,7 @@ 
   Interface_type* lhs_interface_type = lhs_type->interface_type();
   bool lhs_is_empty = lhs_interface_type->is_empty();
 
-  tree lhs_type_tree = lhs_type->get_tree(gogo);
+  tree lhs_type_tree = type_to_tree(lhs_type->get_backend(gogo));
   if (lhs_type_tree == error_mark_node)
     return error_mark_node;
 
@@ -567,7 +567,7 @@ 
   Gogo* gogo = context->gogo();
   tree rhs_type_tree = TREE_TYPE(rhs_tree);
 
-  tree lhs_type_tree = lhs_type->get_tree(gogo);
+  tree lhs_type_tree = type_to_tree(lhs_type->get_backend(gogo));
   if (lhs_type_tree == error_mark_node)
     return error_mark_node;
 
@@ -1041,7 +1041,8 @@ 
   tree ret = var_to_tree(bvar);
   if (POINTER_TYPE_P(TREE_TYPE(ret)) && VOID_TYPE_P(TREE_TYPE(TREE_TYPE(ret))))
     {
-      tree type_tree = this->type()->base()->get_tree(context->gogo());
+      Btype* type_btype = this->type()->base()->get_backend(context->gogo());
+      tree type_tree = type_to_tree(type_btype);
       ret = fold_convert_loc(this->location(), type_tree, ret);
     }
   return ret;
@@ -1119,8 +1120,8 @@ 
   if (this->var_ == NULL_TREE)
     {
       go_assert(this->type_ != NULL && !this->type_->is_sink_type());
-      this->var_ = create_tmp_var(this->type_->get_tree(context->gogo()),
-				  "blank");
+      Btype* bt = this->type_->get_backend(context->gogo());
+      this->var_ = create_tmp_var(type_to_tree(bt), "blank");
     }
   return this->var_;
 }
@@ -1701,16 +1702,18 @@ 
   Gogo* gogo = context->gogo();
   tree type;
   if (this->type_ != NULL && !this->type_->is_abstract())
-    type = this->type_->get_tree(gogo);
+    type = type_to_tree(this->type_->get_backend(gogo));
   else if (this->type_ != NULL && this->type_->float_type() != NULL)
     {
       // We are converting to an abstract floating point type.
-      type = Type::lookup_float_type("float64")->get_tree(gogo);
+      Type* ftype = Type::lookup_float_type("float64");
+      type = type_to_tree(ftype->get_backend(gogo));
     }
   else if (this->type_ != NULL && this->type_->complex_type() != NULL)
     {
       // We are converting to an abstract complex type.
-      type = Type::lookup_complex_type("complex128")->get_tree(gogo);
+      Type* ctype = Type::lookup_complex_type("complex128");
+      type = type_to_tree(ctype->get_backend(gogo));
     }
   else
     {
@@ -1720,9 +1723,15 @@ 
       // not <=, because we need an extra bit for the sign bit.
       int bits = mpz_sizeinbase(this->val_, 2);
       if (bits < INT_TYPE_SIZE)
-	type = Type::lookup_integer_type("int")->get_tree(gogo);
+	{
+	  Type* t = Type::lookup_integer_type("int");
+	  type = type_to_tree(t->get_backend(gogo));
+	}
       else if (bits < 64)
-	type = Type::lookup_integer_type("int64")->get_tree(gogo);
+	{
+	  Type* t = Type::lookup_integer_type("int64");
+	  type = type_to_tree(t->get_backend(gogo));
+	}
       else
 	type = long_long_integer_type_node;
     }
@@ -2028,18 +2037,19 @@ 
   Gogo* gogo = context->gogo();
   tree type;
   if (this->type_ != NULL && !this->type_->is_abstract())
-    type = this->type_->get_tree(gogo);
+    type = type_to_tree(this->type_->get_backend(gogo));
   else if (this->type_ != NULL && this->type_->integer_type() != NULL)
     {
       // We have an abstract integer type.  We just hope for the best.
-      type = Type::lookup_integer_type("int")->get_tree(gogo);
+      type = type_to_tree(Type::lookup_integer_type("int")->get_backend(gogo));
     }
   else
     {
       // If we still have an abstract type here, then this is being
       // used in a constant expression which didn't get reduced.  We
       // just use float64 and hope for the best.
-      type = Type::lookup_float_type("float64")->get_tree(gogo);
+      Type* ft = Type::lookup_float_type("float64");
+      type = type_to_tree(ft->get_backend(gogo));
     }
   return Expression::float_constant_tree(this->val_, type);
 }
@@ -2266,13 +2276,14 @@ 
   Gogo* gogo = context->gogo();
   tree type;
   if (this->type_ != NULL && !this->type_->is_abstract())
-    type = this->type_->get_tree(gogo);
+    type = type_to_tree(this->type_->get_backend(gogo));
   else
     {
       // If we still have an abstract type here, this this is being
       // used in a constant expression which didn't get reduced.  We
       // just use complex128 and hope for the best.
-      type = Type::lookup_complex_type("complex128")->get_tree(gogo);
+      Type* ct = Type::lookup_complex_type("complex128");
+      type = type_to_tree(ct->get_backend(gogo));
     }
   return Expression::complex_constant_tree(this->real_, this->imag_, type);
 }
@@ -2718,7 +2729,7 @@ 
     type_tree = NULL_TREE;
   else
     {
-      type_tree = this->type_->get_tree(gogo);
+      type_tree = type_to_tree(this->type_->get_backend(gogo));
       if (type_tree == error_mark_node)
 	return error_mark_node;
     }
@@ -3344,7 +3355,7 @@ 
 Type_conversion_expression::do_get_tree(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
-  tree type_tree = this->type_->get_tree(gogo);
+  tree type_tree = type_to_tree(this->type_->get_backend(gogo));
   tree expr_tree = this->expr_->get_tree(context);
 
   if (type_tree == error_mark_node
@@ -3601,7 +3612,7 @@ 
   Type* t = this->type_;
   Type* et = this->expr_->type();
 
-  tree type_tree = this->type_->get_tree(context->gogo());
+  tree type_tree = type_to_tree(this->type_->get_backend(context->gogo()));
   tree expr_tree = this->expr_->get_tree(context);
   if (type_tree == error_mark_node || expr_tree == error_mark_node)
     return error_mark_node;
@@ -4304,7 +4315,7 @@ 
 	if (TREE_TYPE(TREE_TYPE(expr)) == ptr_type_node)
 	  {
 	    Type* pt = this->expr_->type()->points_to();
-	    tree ind = pt->get_tree(context->gogo());
+	    tree ind = type_to_tree(pt->get_backend(context->gogo()));
 	    expr = fold_convert_loc(loc, build_pointer_type(ind), expr);
 	  }
 
@@ -5984,7 +5995,8 @@ 
   if (this->left_->type()->is_string_type())
     {
       go_assert(this->op_ == OPERATOR_PLUS);
-      tree string_type = Type::make_string_type()->get_tree(context->gogo());
+      Type* st = Type::make_string_type();
+      tree string_type = type_to_tree(st->get_backend(context->gogo()));
       static tree string_plus_decl;
       return Gogo::call_builtin(&string_plus_decl,
 				this->location(),
@@ -6313,7 +6325,8 @@ 
 
   if (left_type->is_string_type() && right_type->is_string_type())
     {
-      tree string_type = Type::make_string_type()->get_tree(context->gogo());
+      Type* st = Type::make_string_type();
+      tree string_type = type_to_tree(st->get_backend(context->gogo()));
       static tree string_compare_decl;
       left_tree = Gogo::call_builtin(&string_compare_decl,
 				     location,
@@ -7151,7 +7164,7 @@ 
 	return false;
       if (arg_type->named_type() != NULL)
 	arg_type->named_type()->convert(this->gogo_);
-      tree arg_type_tree = arg_type->get_tree(this->gogo_);
+      tree arg_type_tree = type_to_tree(arg_type->get_backend(this->gogo_));
       if (arg_type_tree == error_mark_node)
 	return false;
       unsigned long val_long;
@@ -7197,7 +7210,7 @@ 
 	return false;
       if (st->named_type() != NULL)
 	st->named_type()->convert(this->gogo_);
-      tree struct_tree = st->get_tree(this->gogo_);
+      tree struct_tree = type_to_tree(st->get_backend(this->gogo_));
       go_assert(TREE_CODE(struct_tree) == RECORD_TYPE);
       tree field = TYPE_FIELDS(struct_tree);
       for (unsigned int index = farg->field_index(); index > 0; --index)
@@ -7792,24 +7805,26 @@ 
 	      }
 	    else if (arg_type->map_type() != NULL)
 	      {
+		tree arg_type_tree = type_to_tree(arg_type->get_backend(gogo));
 		static tree map_len_fndecl;
 		val_tree = Gogo::call_builtin(&map_len_fndecl,
 					      location,
 					      "__go_map_len",
 					      1,
 					      integer_type_node,
-					      arg_type->get_tree(gogo),
+					      arg_type_tree,
 					      arg_tree);
 	      }
 	    else if (arg_type->channel_type() != NULL)
 	      {
+		tree arg_type_tree = type_to_tree(arg_type->get_backend(gogo));
 		static tree chan_len_fndecl;
 		val_tree = Gogo::call_builtin(&chan_len_fndecl,
 					      location,
 					      "__go_chan_len",
 					      1,
 					      integer_type_node,
-					      arg_type->get_tree(gogo),
+					      arg_type_tree,
 					      arg_tree);
 	      }
 	    else
@@ -7831,13 +7846,14 @@ 
 	      }
 	    else if (arg_type->channel_type() != NULL)
 	      {
+		tree arg_type_tree = type_to_tree(arg_type->get_backend(gogo));
 		static tree chan_cap_fndecl;
 		val_tree = Gogo::call_builtin(&chan_cap_fndecl,
 					      location,
 					      "__go_chan_cap",
 					      1,
 					      integer_type_node,
-					      arg_type->get_tree(gogo),
+					      arg_type_tree,
 					      arg_tree);
 	      }
 	    else
@@ -7847,7 +7863,8 @@ 
 	if (val_tree == error_mark_node)
 	  return error_mark_node;
 
-	tree type_tree = Type::lookup_integer_type("int")->get_tree(gogo);
+	Type* int_type = Type::lookup_integer_type("int");
+	tree type_tree = type_to_tree(int_type->get_backend(gogo));
 	if (type_tree == TREE_TYPE(val_tree))
 	  return val_tree;
 	else
@@ -7901,8 +7918,8 @@ 
 		    pfndecl = &print_uint64_fndecl;
 		    fnname = "__go_print_uint64";
 		    Type* itype = Type::lookup_integer_type("uint64");
-		    arg = fold_convert_loc(location, itype->get_tree(gogo),
-					   arg);
+		    Btype* bitype = itype->get_backend(gogo);
+		    arg = fold_convert_loc(location, type_to_tree(bitype), arg);
 		  }
 		else if (type->integer_type() != NULL)
 		  {
@@ -7910,8 +7927,8 @@ 
 		    pfndecl = &print_int64_fndecl;
 		    fnname = "__go_print_int64";
 		    Type* itype = Type::lookup_integer_type("int64");
-		    arg = fold_convert_loc(location, itype->get_tree(gogo),
-					   arg);
+		    Btype* bitype = itype->get_backend(gogo);
+		    arg = fold_convert_loc(location, type_to_tree(bitype), arg);
 		  }
 		else if (type->float_type() != NULL)
 		  {
@@ -8038,7 +8055,7 @@ 
 	  return error_mark_node;
 
 	Type *empty = Type::make_interface_type(NULL, BUILTINS_LOCATION);
-	tree empty_tree = empty->get_tree(context->gogo());
+	tree empty_tree = type_to_tree(empty->get_backend(context->gogo()));
 
 	Type* nil_type = Type::make_nil_type();
 	Expression* nil = Expression::make_nil(location);
@@ -8108,7 +8125,8 @@ 
 	    go_assert(saw_errors());
 	    return error_mark_node;
 	  }
-	tree type = Type::lookup_integer_type("int")->get_tree(gogo);
+	Type* int_type = Type::lookup_integer_type("int");
+	tree type = type_to_tree(int_type->get_backend(gogo));
 	tree ret = Expression::integer_constant_tree(val, type);
 	mpz_clear(val);
 	return ret;
@@ -8163,7 +8181,8 @@ 
 	len = save_expr(len);
 
 	Type* element_type = at->element_type();
-	tree element_type_tree = element_type->get_tree(gogo);
+	Btype* element_btype = element_type->get_backend(gogo);
+	tree element_type_tree = type_to_tree(element_btype);
 	if (element_type_tree == error_mark_node)
 	  return error_mark_node;
 	tree element_size = TYPE_SIZE_UNIT(element_type_tree);
@@ -8226,7 +8245,7 @@ 
 	arg2_val = fold_convert_loc(location, ptr_type_node, arg2_val);
 	arg2_len = fold_convert_loc(location, size_type_node, arg2_len);
 
-	tree element_type_tree = element_type->get_tree(gogo);
+	tree element_type_tree = type_to_tree(element_type->get_backend(gogo));
 	if (element_type_tree == error_mark_node)
 	  return error_mark_node;
 	tree element_size = TYPE_SIZE_UNIT(element_type_tree);
@@ -8813,7 +8832,8 @@ 
     {
       if (fatype->points_to() == NULL)
 	fatype = Type::make_pointer_type(fatype);
-      first_arg = fold_convert(fatype->get_tree(context->gogo()), first_arg);
+      Btype* bfatype = fatype->get_backend(context->gogo());
+      first_arg = fold_convert(type_to_tree(bfatype), first_arg);
       if (first_arg == error_mark_node
 	  || TREE_TYPE(first_arg) == error_mark_node)
 	return error_mark_node;
@@ -8910,7 +8930,7 @@ 
       go_assert(i == nargs);
     }
 
-  tree rettype = TREE_TYPE(TREE_TYPE(fntype->get_tree(gogo)));
+  tree rettype = TREE_TYPE(TREE_TYPE(type_to_tree(fntype->get_backend(gogo))));
   if (rettype == error_mark_node)
     {
       delete[] args;
@@ -8943,7 +8963,7 @@ 
   // type which refers to itself.
   if (!DECL_P(fndecl) || !DECL_IS_BUILTIN(fndecl))
     {
-      tree fnt = fntype->get_tree(gogo);
+      tree fnt = type_to_tree(fntype->get_backend(gogo));
       if (fnt == error_mark_node)
 	return error_mark_node;
       fn = fold_convert_loc(location, fnt, fn);
@@ -8995,7 +9015,7 @@ 
   // to the correct type.
   if (TREE_TYPE(ret) == ptr_type_node)
     {
-      tree t = this->type()->base()->get_tree(gogo);
+      tree t = type_to_tree(this->type()->base()->get_backend(gogo));
       ret = fold_convert_loc(location, t, ret);
     }
 
@@ -9469,7 +9489,7 @@ 
       return error_mark_node;
     }
 
-  tree type_tree = array_type->get_tree(gogo);
+  tree type_tree = type_to_tree(array_type->get_backend(gogo));
   if (type_tree == error_mark_node)
     return error_mark_node;
 
@@ -9536,7 +9556,9 @@ 
 	{
 	  // Open array.
 	  tree values = array_type->value_pointer_tree(gogo, array_tree);
-	  tree element_type_tree = array_type->element_type()->get_tree(gogo);
+	  Type* element_type = array_type->element_type();
+	  Btype* belement_type = element_type->get_backend(gogo);
+	  tree element_type_tree = type_to_tree(belement_type);
 	  if (element_type_tree == error_mark_node)
 	    return error_mark_node;
 	  tree element_size = TYPE_SIZE_UNIT(element_type_tree);
@@ -9585,7 +9607,8 @@ 
 				  bad_index, bad_end);
     }
 
-  tree element_type_tree = array_type->element_type()->get_tree(gogo);
+  Type* element_type = array_type->element_type();
+  tree element_type_tree = type_to_tree(element_type->get_backend(gogo));
   if (element_type_tree == error_mark_node)
     return error_mark_node;
   tree element_size = TYPE_SIZE_UNIT(element_type_tree);
@@ -9608,7 +9631,7 @@ 
   tree result_capacity_tree = fold_build2_loc(loc, MINUS_EXPR, length_type,
 					      capacity_tree, start_tree);
 
-  tree struct_tree = this->type()->get_tree(gogo);
+  tree struct_tree = type_to_tree(this->type()->get_backend(gogo));
   go_assert(TREE_CODE(struct_tree) == RECORD_TYPE);
 
   VEC(constructor_elt,gc)* init = VEC_alloc(constructor_elt, gc, 3);
@@ -10098,7 +10121,8 @@ 
   // an uncomparable or unhashable type.
   TREE_NOTHROW(map_index_fndecl) = 0;
 
-  tree val_type_tree = type->val_type()->get_tree(context->gogo());
+  Type* val_type = type->val_type();
+  tree val_type_tree = type_to_tree(val_type->get_backend(context->gogo()));
   if (val_type_tree == error_mark_node)
     return error_mark_node;
   tree ptr_val_type_tree = build_pointer_type(val_type_tree);
@@ -10629,7 +10653,7 @@ 
 tree
 Allocation_expression::do_get_tree(Translate_context* context)
 {
-  tree type_tree = this->type_->get_tree(context->gogo());
+  tree type_tree = type_to_tree(this->type_->get_backend(context->gogo()));
   if (type_tree == error_mark_node)
     return error_mark_node;
   tree size_tree = TYPE_SIZE_UNIT(type_tree);
@@ -10933,7 +10957,7 @@ 
   if (this->vals_ == NULL)
     return this->type_->get_init_tree(gogo, false);
 
-  tree type_tree = this->type_->get_tree(gogo);
+  tree type_tree = type_to_tree(this->type_->get_backend(gogo));
   if (type_tree == error_mark_node)
     return error_mark_node;
   go_assert(TREE_CODE(type_tree) == RECORD_TYPE);
@@ -11269,8 +11293,9 @@ 
 tree
 Fixed_array_construction_expression::do_get_tree(Translate_context* context)
 {
-  return this->get_constructor_tree(context,
-				    this->type()->get_tree(context->gogo()));
+  Type* type = this->type();
+  Btype* btype = type->get_backend(context->gogo());
+  return this->get_constructor_tree(context, type_to_tree(btype));
 }
 
 // Construct an open array.
@@ -11317,7 +11342,8 @@ 
     }
 
   Type* element_type = array_type->element_type();
-  tree element_type_tree = element_type->get_tree(context->gogo());
+  Btype* belement_type = element_type->get_backend(context->gogo());
+  tree element_type_tree = type_to_tree(belement_type);
   if (element_type_tree == error_mark_node)
     return error_mark_node;
 
@@ -11410,7 +11436,7 @@ 
 
   // Build a constructor for the open array.
 
-  tree type_tree = this->type()->get_tree(context->gogo());
+  tree type_tree = type_to_tree(this->type()->get_backend(context->gogo()));
   if (type_tree == error_mark_node)
     return error_mark_node;
   go_assert(TREE_CODE(type_tree) == RECORD_TYPE);
@@ -11587,7 +11613,7 @@ 
 
   Type* key_type = mt->key_type();
   tree id = get_identifier("__key");
-  tree key_type_tree = key_type->get_tree(gogo);
+  tree key_type_tree = type_to_tree(key_type->get_backend(gogo));
   if (key_type_tree == error_mark_node)
     return error_mark_node;
   tree key_field = build_decl(loc, FIELD_DECL, id, key_type_tree);
@@ -11596,7 +11622,7 @@ 
 
   Type* val_type = mt->val_type();
   id = get_identifier("__val");
-  tree val_type_tree = val_type->get_tree(gogo);
+  tree val_type_tree = type_to_tree(val_type->get_backend(gogo));
   if (val_type_tree == error_mark_node)
     return error_mark_node;
   tree val_field = build_decl(loc, FIELD_DECL, id, val_type_tree);
@@ -11699,7 +11725,7 @@ 
 
   tree descriptor = gogo->map_descriptor(mt);
 
-  tree type_tree = this->type_->get_tree(gogo);
+  tree type_tree = type_to_tree(this->type_->get_backend(gogo));
   if (type_tree == error_mark_node)
     return error_mark_node;
 
@@ -12345,10 +12371,12 @@ 
 	   || expr_type->integer_type() != NULL))
       || (expr_type->is_unsafe_pointer_type()
 	  && this->type_->points_to() != NULL))
-    return convert_to_pointer(this->type_->get_tree(gogo), expr_tree);
+    return convert_to_pointer(type_to_tree(this->type_->get_backend(gogo)),
+			      expr_tree);
   else if (expr_type->is_unsafe_pointer_type()
 	   && this->type_->integer_type() != NULL)
-    return convert_to_integer(this->type_->get_tree(gogo), expr_tree);
+    return convert_to_integer(type_to_tree(this->type_->get_backend(gogo)),
+			      expr_tree);
   else if (this->type_->interface_type() != NULL)
     return Expression::convert_interface_to_interface(context, this->type_,
 						      this->expr_->type(),
@@ -12495,7 +12523,8 @@ 
       return error_mark_node;
     }
   Type* element_type = channel_type->element_type();
-  tree element_type_tree = element_type->get_tree(context->gogo());
+  Btype* element_type_btype = element_type->get_backend(context->gogo());
+  tree element_type_tree = type_to_tree(element_type_btype);
 
   tree channel = this->channel_->get_tree(context);
   if (element_type_tree == error_mark_node || channel == error_mark_node)
@@ -12613,11 +12642,11 @@ 
 tree
 Type_info_expression::do_get_tree(Translate_context* context)
 {
-  tree type_tree = this->type_->get_tree(context->gogo());
+  tree type_tree = type_to_tree(this->type_->get_backend(context->gogo()));
   if (type_tree == error_mark_node)
     return error_mark_node;
 
-  tree val_type_tree = this->type()->get_tree(context->gogo());
+  tree val_type_tree = type_to_tree(this->type()->get_backend(context->gogo()));
   go_assert(val_type_tree != error_mark_node);
 
   if (this->type_info_ == TYPE_INFO_SIZE)
@@ -12682,11 +12711,11 @@ 
 tree
 Struct_field_offset_expression::do_get_tree(Translate_context* context)
 {
-  tree type_tree = this->type_->get_tree(context->gogo());
+  tree type_tree = type_to_tree(this->type_->get_backend(context->gogo()));
   if (type_tree == error_mark_node)
     return error_mark_node;
 
-  tree val_type_tree = this->type()->get_tree(context->gogo());
+  tree val_type_tree = type_to_tree(this->type()->get_backend(context->gogo()));
   go_assert(val_type_tree != error_mark_node);
 
   const Struct_field_list* fields = this->type_->fields();
diff -r 24bf02cfb81b go/gogo-tree.cc
--- a/go/gogo-tree.cc	Fri May 06 13:04:22 2011 -0700
+++ b/go/gogo-tree.cc	Fri May 06 17:01:19 2011 -0700
@@ -909,10 +909,13 @@ 
 	    Type* type = named_constant->type();
 	    if (type != NULL && !type->is_abstract())
 	      {
-		if (!type->is_error())
-		  expr_tree = fold_convert(type->get_tree(gogo), expr_tree);
+		if (type->is_error())
+		  expr_tree = error_mark_node;
 		else
-		  expr_tree = error_mark_node;
+		  {
+		    Btype* btype = type->get_backend(gogo);
+		    expr_tree = fold_convert(type_to_tree(btype), expr_tree);
+		  }
 	      }
 	    if (expr_tree == error_mark_node)
 	      decl = error_mark_node;
@@ -939,7 +942,7 @@ 
     case NAMED_OBJECT_TYPE:
       {
 	Named_type* named_type = this->u_.type_value;
-	tree type_tree = named_type->get_tree(gogo);
+	tree type_tree = type_to_tree(named_type->get_backend(gogo));
 	if (type_tree == error_mark_node)
 	  decl = error_mark_node;
 	else
@@ -1104,7 +1107,7 @@ 
 {
   if (this->fndecl_ == NULL_TREE)
     {
-      tree functype = this->type_->get_tree(gogo);
+      tree functype = type_to_tree(this->type_->get_backend(gogo));
       if (functype == error_mark_node)
 	this->fndecl_ = error_mark_node;
       else
@@ -1217,7 +1220,7 @@ 
 	    }
 	}
 
-      tree functype = this->fntype_->get_tree(gogo);
+      tree functype = type_to_tree(this->fntype_->get_backend(gogo));
       tree decl;
       if (functype == error_mark_node)
 	decl = error_mark_node;
@@ -1424,7 +1427,7 @@ 
 	  else
 	    {
 	      source_location loc = (*p)->location();
-	      tree type_tree = type->get_tree(gogo);
+	      tree type_tree = type_to_tree(type->get_backend(gogo));
 	      tree space = gogo->allocate_memory(type,
 						 TYPE_SIZE_UNIT(type_tree),
 						 loc);
@@ -1712,7 +1715,7 @@ 
 	return NULL_TREE;
     }
   Type* type = Type::lookup_integer_type(name);
-  return type->get_tree(go_get_gogo());
+  return type_to_tree(type->get_backend(go_get_gogo()));
 }
 
 // Return the type to use for a mode.
@@ -1743,7 +1746,7 @@ 
 	    return long_double_type_node;
 	  return NULL_TREE;
 	}
-      return type->get_tree(go_get_gogo());
+      return type_to_tree(type->get_backend(go_get_gogo()));
     }
   else if (mc == MODE_COMPLEX_FLOAT)
     {
@@ -1763,7 +1766,7 @@ 
 	    return complex_long_double_type_node;
 	  return NULL_TREE;
 	}
-      return type->get_tree(go_get_gogo());
+      return type_to_tree(type->get_backend(go_get_gogo()));
     }
   else
     return NULL_TREE;
@@ -1887,7 +1890,7 @@ 
 tree
 Gogo::go_string_constant_tree(const std::string& val)
 {
-  tree string_type = Type::make_string_type()->get_tree(this);
+  tree string_type = type_to_tree(Type::make_string_type()->get_backend(this));
 
   VEC(constructor_elt, gc)* init = VEC_alloc(constructor_elt, gc, 2);
 
@@ -2016,13 +2019,15 @@ 
 
   tree map_entry_type = make_node(RECORD_TYPE);
 
+  Btype* bkey_type = keytype->get_backend(this);
+  Btype* bval_type = valtype->get_backend(this);
   map_entry_type = Gogo::builtin_struct(NULL, "__map", map_entry_type, 3,
 					"__next",
 					build_pointer_type(map_entry_type),
 					"__key",
-					keytype->get_tree(this),
+					type_to_tree(bkey_type),
 					"__val",
-					valtype->get_tree(this));
+					type_to_tree(bval_type));
   if (map_entry_type == error_mark_node)
     {
       p->second = error_mark_node;
@@ -2097,7 +2102,8 @@ 
 Gogo::map_descriptor_type()
 {
   static tree struct_type;
-  tree dtype = Type::make_type_descriptor_type()->get_tree(this);
+  Type* tdt = Type::make_type_descriptor_type();
+  tree dtype = type_to_tree(tdt->get_backend(this));
   dtype = build_qualified_type(dtype, TYPE_QUAL_CONST);
   return Gogo::builtin_struct(&struct_type, "__go_map_descriptor", NULL_TREE,
 			      4,
@@ -2238,7 +2244,8 @@ 
     decl_name = this->type_descriptor_decl_name(name->named_object(),
 						name->in_function());
   tree id = get_identifier_from_string(decl_name);
-  tree descriptor_type_tree = initializer->type()->get_tree(this);
+  Type* init_type = initializer->type();
+  tree descriptor_type_tree = type_to_tree(init_type->get_backend(this));
   if (descriptor_type_tree == error_mark_node)
     {
       *pdecl = error_mark_node;
diff -r 24bf02cfb81b go/gogo.cc
--- a/go/gogo.cc	Fri May 06 13:04:22 2011 -0700
+++ b/go/gogo.cc	Fri May 06 17:01:19 2011 -0700
@@ -3703,7 +3703,7 @@ 
 	    }
 
 	  std::string n = Gogo::unpack_hidden_name(name);
-	  Btype* btype = tree_to_type(type->get_tree(gogo));
+	  Btype* btype = type->get_backend(gogo);
 
 	  Bvariable* bvar;
 	  if (this->is_global_)
@@ -3753,7 +3753,7 @@ 
 	{
 	  if (this->is_in_heap())
 	    type = Type::make_pointer_type(type);
-	  Btype* btype = tree_to_type(type->get_tree(gogo));
+	  Btype* btype = type->get_backend(gogo);
 	  tree fndecl = function->func_value()->get_decl();
 	  Bfunction* bfunction = tree_to_function(fndecl);
 	  std::string n = Gogo::unpack_hidden_name(name);
diff -r 24bf02cfb81b go/statements.cc
--- a/go/statements.cc	Fri May 06 13:04:22 2011 -0700
+++ b/go/statements.cc	Fri May 06 17:01:19 2011 -0700
@@ -375,7 +375,7 @@ 
   else
     bfunction = tree_to_function(function->func_value()->get_decl());
 
-  Btype* btype = tree_to_type(this->type()->get_tree(context->gogo()));
+  Btype* btype = this->type()->get_backend(context->gogo());
 
   Bexpression* binit;
   if (this->init_ == NULL)
diff -r 24bf02cfb81b go/types.cc
--- a/go/types.cc	Fri May 06 13:04:22 2011 -0700
+++ b/go/types.cc	Fri May 06 17:01:19 2011 -0700
@@ -37,7 +37,7 @@ 
 // Class Type.
 
 Type::Type(Type_classification classification)
-  : classification_(classification), tree_(NULL_TREE),
+  : classification_(classification), btype_(NULL),
     type_descriptor_decl_(NULL_TREE)
 {
 }
@@ -833,55 +833,56 @@ 
 
 // A hash table mapping unnamed types to trees.
 
-Type::Type_trees Type::type_trees;
+Type::Type_btypes Type::type_btypes;
 
 // Return a tree representing this type.
 
-tree
-Type::get_tree(Gogo* gogo)
-{
-  if (this->tree_ != NULL)
-    return this->tree_;
+Btype*
+Type::get_backend(Gogo* gogo)
+{
+  if (this->btype_ != NULL)
+    return this->btype_;
 
   if (this->forward_declaration_type() != NULL
       || this->named_type() != NULL)
-    return type_to_tree(this->get_btype_without_hash(gogo));
+    return this->get_btype_without_hash(gogo);
 
   if (this->is_error_type())
-    return error_mark_node;
+    return gogo->backend()->error_type();
 
   // To avoid confusing the backend, translate all identical Go types
-  // to the same backend type.  We use a hash table to do that.  There
-  // is no need to use the hash table for named types, as named types
-  // are only identical to themselves.
-
-  std::pair<Type*, tree> val(this, NULL);
-  std::pair<Type_trees::iterator, bool> ins =
-    Type::type_trees.insert(val);
-  if (!ins.second && ins.first->second != NULL_TREE)
+  // to the same backend representation.  We use a hash table to do
+  // that.  There is no need to use the hash table for named types, as
+  // named types are only identical to themselves.
+
+  std::pair<Type*, Btype*> val(this, NULL);
+  std::pair<Type_btypes::iterator, bool> ins =
+    Type::type_btypes.insert(val);
+  if (!ins.second && ins.first->second != NULL)
     {
       if (gogo != NULL && gogo->named_types_are_converted())
-	this->tree_ = ins.first->second;
+	this->btype_ = ins.first->second;
       return ins.first->second;
     }
 
-  tree t = type_to_tree(this->get_btype_without_hash(gogo));
-
-  if (ins.first->second == NULL_TREE)
-    ins.first->second = t;
+  Btype* bt = this->get_btype_without_hash(gogo);
+
+  if (ins.first->second == NULL)
+    ins.first->second = bt;
   else
     {
-      // We have already created a tree 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 built.
-      t = ins.first->second;
+      // 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
+      // built.
+      bt = ins.first->second;
       if (gogo == NULL || !gogo->named_types_are_converted())
-	return t;
-      this->tree_ = t;
-    }
-
-  return t;
+	return bt;
+      this->btype_ = bt;
+    }
+
+  return bt;
 }
 
 // Return the backend representation for a type without looking in the
@@ -891,9 +892,9 @@ 
 Btype*
 Type::get_btype_without_hash(Gogo* gogo)
 {
-  if (this->tree_ == NULL_TREE)
-    {
-      Btype* bt = tree_to_type(this->do_get_tree(gogo));
+  if (this->btype_ == NULL)
+    {
+      Btype* bt = this->do_get_backend(gogo);
 
       // For a recursive function or pointer type, we will temporarily
       // return a circular pointer type during the recursion.  We
@@ -906,11 +907,9 @@ 
       if (gogo == NULL || !gogo->named_types_are_converted())
 	return bt;
 
-      tree t = type_to_tree(bt);
-      this->tree_ = t;
-    }
-
-  return tree_to_type(this->tree_);
+      this->btype_ = bt;
+    }
+  return this->btype_;
 }
 
 // Return a tree representing a zero initialization for this type.
@@ -918,7 +917,7 @@ 
 tree
 Type::get_init_tree(Gogo* gogo, bool is_clear)
 {
-  tree type_tree = this->get_tree(gogo);
+  tree type_tree = type_to_tree(this->get_backend(gogo));
   if (type_tree == error_mark_node)
     return error_mark_node;
   return this->do_get_init_tree(gogo, type_tree, is_clear);
@@ -1585,9 +1584,9 @@ 
   { }
 
  protected:
-  tree
-  do_get_tree(Gogo* gogo)
-  { return type_to_tree(gogo->backend()->error_type()); }
+  Btype*
+  do_get_backend(Gogo* gogo)
+  { return gogo->backend()->error_type(); }
 
   tree
   do_get_init_tree(Gogo*, tree, bool)
@@ -1623,12 +1622,9 @@ 
   { }
 
  protected:
-  tree
-  do_get_tree(Gogo* gogo)
-  {
-    Btype* btype = gogo->backend()->void_type();
-    return type_to_tree(btype);
-  }
+  Btype*
+  do_get_backend(Gogo* gogo)
+  { return gogo->backend()->void_type(); }
 
   tree
   do_get_init_tree(Gogo*, tree, bool)
@@ -1664,12 +1660,9 @@ 
   { }
 
  protected:
-  tree
-  do_get_tree(Gogo* gogo)
-  {
-    Btype* btype = gogo->backend()->bool_type();
-    return type_to_tree(btype);
-  }
+  Btype*
+  do_get_backend(Gogo* gogo)
+  { return gogo->backend()->bool_type(); }
 
   tree
   do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
@@ -1805,18 +1798,15 @@ 
 
 // Convert an Integer_type to the backend representation.
 
-tree
-Integer_type::do_get_tree(Gogo* gogo)
+Btype*
+Integer_type::do_get_backend(Gogo* gogo)
 {
   if (this->is_abstract_)
     {
       go_assert(saw_errors());
-      return error_mark_node;
-    }
-
-  Btype* btype = gogo->backend()->integer_type(this->is_unsigned_,
-					       this->bits_);
-  return type_to_tree(btype);
+      return gogo->backend()->error_type();
+    }
+  return gogo->backend()->integer_type(this->is_unsigned_, this->bits_);
 }
 
 tree
@@ -1946,11 +1936,10 @@ 
 
 // Convert to the backend representation.
 
-tree
-Float_type::do_get_tree(Gogo* gogo)
-{
-  Btype* btype = gogo->backend()->float_type(this->bits_);
-  return type_to_tree(btype);
+Btype*
+Float_type::do_get_backend(Gogo* gogo)
+{
+  return gogo->backend()->float_type(this->bits_);
 }
 
 tree
@@ -2083,10 +2072,10 @@ 
 
 // Convert to the backend representation.
 
-tree
-Complex_type::do_get_tree(Gogo* gogo)
-{
-  return type_to_tree(gogo->backend()->complex_type(this->bits_));
+Btype*
+Complex_type::do_get_backend(Gogo* gogo)
+{
+  return gogo->backend()->complex_type(this->bits_);
 }
 
 // Zero initializer.
@@ -2161,8 +2150,8 @@ 
 // Convert String_type to the backend representation.  A string is a
 // struct with two fields: a pointer to the characters and a length.
 
-tree
-String_type::do_get_tree(Gogo* gogo)
+Btype*
+String_type::do_get_backend(Gogo* gogo)
 {
   static Btype* backend_string_type;
   if (backend_string_type == NULL)
@@ -2172,17 +2161,17 @@ 
       Type* b = gogo->lookup_global("byte")->type_value();
       Type* pb = Type::make_pointer_type(b);
       fields[0].name = "__data";
-      fields[0].btype = tree_to_type(pb->get_tree(gogo));
+      fields[0].btype = pb->get_backend(gogo);
       fields[0].location = UNKNOWN_LOCATION;
 
       Type* int_type = Type::lookup_integer_type("int");
       fields[1].name = "__length";
-      fields[1].btype = tree_to_type(int_type->get_tree(gogo));
+      fields[1].btype = int_type->get_backend(gogo);
       fields[1].location = UNKNOWN_LOCATION;
 
       backend_string_type = gogo->backend()->struct_type(fields);
     }
-  return type_to_tree(backend_string_type);
+  return backend_string_type;
 }
 
 // Return a tree for the length of STRING.
@@ -2316,8 +2305,8 @@ 
   { }
 
  protected:
-  tree
-  do_get_tree(Gogo*)
+  Btype*
+  do_get_backend(Gogo*)
   { go_unreachable(); }
 
   tree
@@ -2601,8 +2590,8 @@ 
 
 // Get the tree for a function type.
 
-tree
-Function_type::do_get_tree(Gogo* gogo)
+Btype*
+Function_type::do_get_backend(Gogo* gogo)
 {
   Backend::Btyped_identifier breceiver;
   if (this->receiver_ != NULL)
@@ -2614,7 +2603,7 @@ 
       Type* rtype = this->receiver_->type();
       if (rtype->points_to() == NULL)
 	rtype = Type::make_pointer_type(rtype);
-      breceiver.btype = tree_to_type(rtype->get_tree(gogo));
+      breceiver.btype = rtype->get_backend(gogo);
       breceiver.location = this->receiver_->location();
     }
 
@@ -2628,7 +2617,7 @@ 
 	   ++p, ++i)
 	{
 	  bparameters[i].name = Gogo::unpack_hidden_name(p->name());
-	  bparameters[i].btype = tree_to_type(p->type()->get_tree(gogo));
+	  bparameters[i].btype = p->type()->get_backend(gogo);
 	  bparameters[i].location = p->location();
 	}
       go_assert(i == bparameters.size());
@@ -2644,15 +2633,14 @@ 
 	   ++p, ++i)
 	{
 	  bresults[i].name = Gogo::unpack_hidden_name(p->name());
-	  bresults[i].btype = tree_to_type(p->type()->get_tree(gogo));
+	  bresults[i].btype = p->type()->get_backend(gogo);
 	  bresults[i].location = p->location();
 	}
       go_assert(i == bresults.size());
     }
 
-  Btype* fntype = gogo->backend()->function_type(breceiver, bparameters,
-						 bresults, this->location());
-  return type_to_tree(fntype);
+  return gogo->backend()->function_type(breceiver, bparameters, bresults,
+					this->location());
 }
 
 // Functions are initialized to NULL.
@@ -3060,12 +3048,11 @@ 
 
 // The tree for a pointer type.
 
-tree
-Pointer_type::do_get_tree(Gogo* gogo)
-{
-  Btype* to_btype = tree_to_type(this->to_type_->get_tree(gogo));
-  Btype* btype = gogo->backend()->pointer_type(to_btype);
-  return type_to_tree(btype);
+Btype*
+Pointer_type::do_get_backend(Gogo* gogo)
+{
+  Btype* to_btype = this->to_type_->get_backend(gogo);
+  return gogo->backend()->pointer_type(to_btype);
 }
 
 // Initialize a pointer type.
@@ -3217,12 +3204,9 @@ 
   { }
 
  protected:
-  tree
-  do_get_tree(Gogo* gogo)
-  {
-    Btype* bt = gogo->backend()->pointer_type(gogo->backend()->void_type());
-    return type_to_tree(bt);
-  }
+  Btype*
+  do_get_backend(Gogo* gogo)
+  { return gogo->backend()->pointer_type(gogo->backend()->void_type()); }
 
   tree
   do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
@@ -3271,8 +3255,12 @@ 
     return false;
   }
 
-  tree
-  do_get_tree(Gogo*);
+  Btype*
+  do_get_backend(Gogo* gogo)
+  {
+    go_assert(saw_errors());
+    return gogo->backend()->error_type();
+  }
 
   tree
   do_get_init_tree(Gogo*, tree, bool)
@@ -3301,21 +3289,6 @@ 
   Call_expression* call_;
 };
 
-// Return the tree for a call result.
-
-tree
-Call_multiple_result_type::do_get_tree(Gogo* gogo)
-{
-  Function_type* fntype = this->call_->get_function_type();
-  go_assert(fntype != NULL);
-  const Typed_identifier_list* results = fntype->results();
-  go_assert(results != NULL && results->size() > 1);
-  tree fntype_tree = fntype->get_tree(gogo);
-  if (fntype_tree == error_mark_node)
-    return error_mark_node;
-  return TREE_TYPE(fntype_tree);
-}
-
 // Make a call result type.
 
 Type*
@@ -3780,7 +3753,7 @@ 
        ++p, ++i)
     {
       (*bfields)[i].name = Gogo::unpack_hidden_name(p->field_name());
-      (*bfields)[i].btype = tree_to_type(p->type()->get_tree(gogo));
+      (*bfields)[i].btype = p->type()->get_backend(gogo);
       (*bfields)[i].location = p->location();
     }
   go_assert(i == fields->size());
@@ -3788,13 +3761,12 @@ 
 
 // Get the tree for a struct type.
 
-tree
-Struct_type::do_get_tree(Gogo* gogo)
+Btype*
+Struct_type::do_get_backend(Gogo* gogo)
 {
   std::vector<Backend::Btyped_identifier> bfields;
   get_backend_struct_fields(gogo, this->fields_, &bfields);
-  Btype* btype = gogo->backend()->struct_type(bfields);
-  return type_to_tree(btype);
+  return gogo->backend()->struct_type(bfields);
 }
 
 // Initialize struct fields.
@@ -4382,7 +4354,7 @@ 
 	    t = Type::lookup_integer_type("int");
 	  else if (t->is_abstract())
 	    t = t->make_non_abstract_type();
-	  tree tt = t->get_tree(gogo);
+	  tree tt = type_to_tree(t->get_backend(gogo));
 	  this->length_tree_ = Expression::integer_constant_tree(val, tt);
 	  mpz_clear(val);
 	}
@@ -4420,7 +4392,7 @@ 
   bfields->resize(3);
 
   Type* pet = Type::make_pointer_type(type->element_type());
-  Btype* pbet = tree_to_type(pet->get_tree(gogo));
+  Btype* pbet = pet->get_backend(gogo);
 
   Backend::Btyped_identifier* p = &(*bfields)[0];
   p->name = "__values";
@@ -4431,12 +4403,12 @@ 
 
   p = &(*bfields)[1];
   p->name = "__count";
-  p->btype = tree_to_type(int_type->get_tree(gogo));
+  p->btype = int_type->get_backend(gogo);
   p->location = UNKNOWN_LOCATION;
 
   p = &(*bfields)[2];
   p->name = "__capacity";
-  p->btype = tree_to_type(int_type->get_tree(gogo));
+  p->btype = int_type->get_backend(gogo);
   p->location = UNKNOWN_LOCATION;
 }
 
@@ -4445,21 +4417,20 @@ 
 // just like an array in C.  An open array is a struct with three
 // fields: a data pointer, the length, and the capacity.
 
-tree
-Array_type::do_get_tree(Gogo* gogo)
+Btype*
+Array_type::do_get_backend(Gogo* gogo)
 {
   if (this->length_ == NULL)
     {
       std::vector<Backend::Btyped_identifier> bfields;
       get_backend_slice_fields(gogo, this, &bfields);
-      return type_to_tree(gogo->backend()->struct_type(bfields));
+      return gogo->backend()->struct_type(bfields);
     }
   else
     {
       Btype* element = this->get_backend_element(gogo);
       Bexpression* len = this->get_backend_length(gogo);
-      Btype* ret = gogo->backend()->array_type(element, len);
-      return type_to_tree(ret);
+      return gogo->backend()->array_type(element, len);
     }
 }
 
@@ -4467,7 +4438,7 @@ 
 Btype*
 Array_type::get_backend_element(Gogo* gogo)
 {
-  return tree_to_type(this->element_type_->get_tree(gogo));
+  return this->element_type_->get_backend(gogo);
 }
 
 // Return the backend representation of the length.
@@ -4543,7 +4514,7 @@ 
   go_assert(this->length_ == NULL);
 
   Gogo* gogo = context->gogo();
-  tree type_tree = this->get_tree(gogo);
+  tree type_tree = type_to_tree(this->get_backend(gogo));
   if (type_tree == error_mark_node)
     return error_mark_node;
 
@@ -4555,7 +4526,7 @@ 
   go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(count_field)),
 		    "__count") == 0);
 
-  tree element_type_tree = this->element_type_->get_tree(gogo);
+  tree element_type_tree = type_to_tree(this->element_type_->get_backend(gogo));
   if (element_type_tree == error_mark_node)
     return error_mark_node;
   tree element_size_tree = TYPE_SIZE_UNIT(element_type_tree);
@@ -5061,8 +5032,8 @@ 
 // represented as a pointer to a struct.  The struct is __go_map in
 // libgo/map.h.
 
-tree
-Map_type::do_get_tree(Gogo* gogo)
+Btype*
+Map_type::do_get_backend(Gogo* gogo)
 {
   static Btype* backend_map_type;
   if (backend_map_type == NULL)
@@ -5071,12 +5042,12 @@ 
 
       Type* pdt = Type::make_type_descriptor_ptr_type();
       bfields[0].name = "__descriptor";
-      bfields[0].btype = tree_to_type(pdt->get_tree(gogo));
+      bfields[0].btype = pdt->get_backend(gogo);
       bfields[0].location = BUILTINS_LOCATION;
 
       Type* uintptr_type = Type::lookup_integer_type("uintptr");
       bfields[1].name = "__element_count";
-      bfields[1].btype = tree_to_type(uintptr_type->get_tree(gogo));
+      bfields[1].btype = uintptr_type->get_backend(gogo);
       bfields[1].location = BUILTINS_LOCATION;
 
       bfields[2].name = "__bucket_count";
@@ -5094,7 +5065,7 @@ 
       bt = gogo->backend()->named_type("__go_map", bt, BUILTINS_LOCATION);
       backend_map_type = gogo->backend()->pointer_type(bt);
     }
-  return type_to_tree(backend_map_type);
+  return backend_map_type;
 }
 
 // Initialize a map.
@@ -5132,7 +5103,7 @@ 
 					   location);
     }
 
-  tree map_type = this->get_tree(context->gogo());
+  tree map_type = type_to_tree(this->get_backend(context->gogo()));
 
   static tree new_map_fndecl;
   tree ret = Gogo::call_builtin(&new_map_fndecl,
@@ -5329,8 +5300,8 @@ 
 // __go_channel struct.  The __go_channel struct is defined in
 // libgo/runtime/channel.h.
 
-tree
-Channel_type::do_get_tree(Gogo* gogo)
+Btype*
+Channel_type::do_get_backend(Gogo* gogo)
 {
   static Btype* backend_channel_type;
   if (backend_channel_type == NULL)
@@ -5340,7 +5311,7 @@ 
       bt = gogo->backend()->named_type("__go_channel", bt, BUILTINS_LOCATION);
       backend_channel_type = gogo->backend()->pointer_type(bt);
     }
-  return type_to_tree(backend_channel_type);
+  return backend_channel_type;
 }
 
 // Initialize a channel variable.
@@ -5361,9 +5332,9 @@ 
 				      source_location location)
 {
   Gogo* gogo = context->gogo();
-  tree channel_type = this->get_tree(gogo);
-
-  tree element_tree = this->element_type_->get_tree(gogo);
+  tree channel_type = type_to_tree(this->get_backend(gogo));
+
+  tree element_tree = type_to_tree(this->element_type_->get_backend(gogo));
   tree element_size_tree = size_in_bytes(element_tree);
 
   tree bad_index = NULL_TREE;
@@ -6003,12 +5974,12 @@ 
 
       Type* pdt = Type::make_type_descriptor_ptr_type();
       bfields[0].name = "__type_descriptor";
-      bfields[0].btype = tree_to_type(pdt->get_tree(gogo));
+      bfields[0].btype = pdt->get_backend(gogo);
       bfields[0].location = UNKNOWN_LOCATION;
 
       Type* vt = Type::make_pointer_type(Type::make_void_type());
       bfields[1].name = "__object";
-      bfields[1].btype = tree_to_type(vt->get_tree(gogo));
+      bfields[1].btype = vt->get_backend(gogo);
       bfields[1].location = UNKNOWN_LOCATION;
 
       empty_interface_type = gogo->backend()->struct_type(bfields);
@@ -6030,7 +6001,7 @@ 
 
   Type* pdt = Type::make_type_descriptor_ptr_type();
   mfields[0].name = "__type_descriptor";
-  mfields[0].btype = tree_to_type(pdt->get_tree(gogo));
+  mfields[0].btype = pdt->get_backend(gogo);
   mfields[0].location = loc;
 
   std::string last_name = "";
@@ -6040,7 +6011,7 @@ 
        ++p, ++i)
     {
       mfields[i].name = Gogo::unpack_hidden_name(p->name());
-      mfields[i].btype = tree_to_type(p->type()->get_tree(gogo));
+      mfields[i].btype = p->type()->get_backend(gogo);
       mfields[i].location = loc;
       // Sanity check: the names should be sorted.
       go_assert(p->name() > last_name);
@@ -6057,7 +6028,7 @@ 
 
   Type* vt = Type::make_pointer_type(Type::make_void_type());
   (*bfields)[1].name = "__object";
-  (*bfields)[1].btype = tree_to_type(vt->get_tree(gogo));
+  (*bfields)[1].btype = vt->get_backend(gogo);
   (*bfields)[1].location = UNKNOWN_LOCATION;
 }
 
@@ -6068,20 +6039,16 @@ 
 // interface to be used with the object.  The third field is the value
 // of the object itself.
 
-tree
-Interface_type::do_get_tree(Gogo* gogo)
+Btype*
+Interface_type::do_get_backend(Gogo* gogo)
 {
   if (this->methods_ == NULL)
-    {
-      Btype* bt = Interface_type::get_backend_empty_interface_type(gogo);
-      return type_to_tree(bt);
-    }
+    return Interface_type::get_backend_empty_interface_type(gogo);
   else
     {
       std::vector<Backend::Btyped_identifier> bfields;
       get_backend_interface_fields(gogo, this, &bfields);
-      Btype* bt = gogo->backend()->struct_type(bfields);
-      return type_to_tree(bt);
+      return gogo->backend()->struct_type(bfields);
     }
 }
 
@@ -7200,11 +7167,11 @@ 
 
 // Get a tree for a named type.
 
-tree
-Named_type::do_get_tree(Gogo* gogo)
+Btype*
+Named_type::do_get_backend(Gogo* gogo)
 {
   if (this->is_error_)
-    return error_mark_node;
+    return gogo->backend()->error_type();
 
   Btype* bt = this->named_btype_;
 
@@ -7213,7 +7180,7 @@ 
       // We have not completed converting named types.  NAMED_BTYPE_
       // is a placeholder and we shouldn't do anything further.
       if (bt != NULL)
-	return type_to_tree(bt);
+	return bt;
 
       // We don't build dependencies for types whose sizes do not
       // change or are not relevant, so we may see them here while
@@ -7221,7 +7188,7 @@ 
       this->create_placeholder(gogo);
       bt = this->named_btype_;
       go_assert(bt != NULL);
-      return type_to_tree(bt);
+      return bt;
     }
 
   // We are not converting types.  This should only be called if the
@@ -7229,7 +7196,7 @@ 
   if (!this->is_converted_)
     {
       go_assert(saw_errors());
-      return error_mark_node;
+      return gogo->backend()->error_type();
     }
 
   go_assert(bt != NULL);
@@ -7240,7 +7207,7 @@ 
   switch (base->classification())
     {
     case TYPE_ERROR:
-      return error_mark_node;
+      return gogo->backend()->error_type();
 
     case TYPE_VOID:
     case TYPE_BOOLEAN:
@@ -7254,7 +7221,7 @@ 
     case TYPE_STRUCT:
     case TYPE_ARRAY:
     case TYPE_INTERFACE:
-      return type_to_tree(bt);
+      return bt;
 
     case TYPE_FUNCTION:
       // Don't build a circular data structure.  GENERIC can't handle
@@ -7262,8 +7229,7 @@ 
       if (this->seen_ > 0)
 	{
 	  this->is_circular_ = true;
-	  bt1 = gogo->backend()->circular_pointer_type(bt, true);
-	  return type_to_tree(bt1);
+	  return gogo->backend()->circular_pointer_type(bt, true);
 	}
       ++this->seen_;
       bt1 = Type::get_named_base_btype(gogo, base);
@@ -7272,7 +7238,7 @@ 
 	bt1 = gogo->backend()->circular_pointer_type(bt, true);
       if (!gogo->backend()->set_placeholder_pointer_type(bt, bt1))
 	bt = gogo->backend()->error_type();
-      return type_to_tree(bt);
+      return bt;
 
     case TYPE_POINTER:
       // Don't build a circular data structure. GENERIC can't handle
@@ -7280,8 +7246,7 @@ 
       if (this->seen_ > 0)
 	{
 	  this->is_circular_ = true;
-	  bt1 = gogo->backend()->circular_pointer_type(bt, false);
-	  return type_to_tree(bt1);
+	  return gogo->backend()->circular_pointer_type(bt, false);
 	}
       ++this->seen_;
       bt1 = Type::get_named_base_btype(gogo, base);
@@ -7290,7 +7255,7 @@ 
 	bt1 = gogo->backend()->circular_pointer_type(bt, false);
       if (!gogo->backend()->set_placeholder_pointer_type(bt, bt1))
 	bt = gogo->backend()->error_type();
-      return type_to_tree(bt);
+      return bt;
 
     default:
     case TYPE_SINK:
@@ -8409,23 +8374,22 @@ 
 
 // Get the backend representation for the type.
 
-tree
-Forward_declaration_type::do_get_tree(Gogo* gogo)
+Btype*
+Forward_declaration_type::do_get_backend(Gogo* gogo)
 {
   if (this->is_defined())
-    return type_to_tree(Type::get_named_base_btype(gogo, this->real_type()));
+    return Type::get_named_base_btype(gogo, this->real_type());
 
   if (this->warned_)
-    return error_mark_node;
+    return gogo->backend()->error_type();
 
   // We represent an undefined type as a struct with no fields.  That
   // should work fine for the backend, since the same case can arise
   // in C.
   std::vector<Backend::Btyped_identifier> fields;
   Btype* bt = gogo->backend()->struct_type(fields);
-  bt = gogo->backend()->named_type(this->name(), bt,
-				   this->named_object()->location());
-  return type_to_tree(bt);
+  return gogo->backend()->named_type(this->name(), bt,
+				     this->named_object()->location());
 }
 
 // Build a type descriptor for a forwarded type.
diff -r 24bf02cfb81b go/types.h
--- a/go/types.h	Fri May 06 13:04:22 2011 -0700
+++ b/go/types.h	Fri May 06 17:01:19 2011 -0700
@@ -821,9 +821,9 @@ 
   static void
   convert_builtin_named_types(Gogo*);
 
-  // Return a tree representing this type.
-  tree
-  get_tree(Gogo*);
+  // Return the backend representation of this type.
+  Btype*
+  get_backend(Gogo*);
 
   // Return a tree representing a zero initialization for this type.
   // This will be something like an INTEGER_CST or a CONSTRUCTOR.  If
@@ -892,9 +892,8 @@ 
   virtual bool
   do_check_make_expression(Expression_list* args, source_location);
 
-
-  virtual tree
-  do_get_tree(Gogo*) = 0;
+  virtual Btype*
+  do_get_backend(Gogo*) = 0;
 
   virtual tree
   do_get_init_tree(Gogo*, tree, bool) = 0;
@@ -1103,20 +1102,21 @@ 
   Btype*
   get_btype_without_hash(Gogo*);
 
-  // A mapping from Type to tree, used to ensure that the GIMPLE
+  // A mapping from Type to Btype*, used to ensure that the backend
   // representation of identical types is identical.
-  typedef Unordered_map_hash(const Type*, tree, Type_hash_identical,
-			     Type_identical) Type_trees;
-
-  static Type_trees type_trees;
+  typedef Unordered_map_hash(const Type*, Btype*, Type_hash_identical,
+			     Type_identical) Type_btypes;
+
+  static Type_btypes type_btypes;
 
   // A list of builtin named types.
   static std::vector<Named_type*> named_builtin_types;
 
   // The type classification.
   Type_classification classification_;
-  // The tree representation of the type, once it has been determined.
-  tree tree_;
+  // The backend representation of the type, once it has been
+  // determined.
+  Btype* btype_;
   // The decl for the type descriptor for this type.  This starts out
   // as NULL and is filled in as needed.
   tree type_descriptor_decl_;
@@ -1331,8 +1331,8 @@ 
   unsigned int
   do_hash_for_method(Gogo*) const;
 
-  tree
-  do_get_tree(Gogo*);
+  Btype*
+  do_get_backend(Gogo*);
 
   tree
   do_get_init_tree(Gogo*, tree, bool);
@@ -1403,8 +1403,8 @@ 
   unsigned int
   do_hash_for_method(Gogo*) const;
 
-  tree
-  do_get_tree(Gogo*);
+  Btype*
+  do_get_backend(Gogo*);
 
   tree
   do_get_init_tree(Gogo*, tree, bool);
@@ -1471,8 +1471,8 @@ 
   unsigned int
   do_hash_for_method(Gogo*) const;
 
-  tree
-  do_get_tree(Gogo*);
+  Btype*
+  do_get_backend(Gogo*);
 
   tree
   do_get_init_tree(Gogo*, tree, bool);
@@ -1527,8 +1527,8 @@ 
   do_has_pointer() const
   { return true; }
 
-  tree
-  do_get_tree(Gogo*);
+  Btype*
+  do_get_backend(Gogo*);
 
   tree
   do_get_init_tree(Gogo* gogo, tree, bool);
@@ -1643,8 +1643,8 @@ 
   unsigned int
   do_hash_for_method(Gogo*) const;
 
-  tree
-  do_get_tree(Gogo*);
+  Btype*
+  do_get_backend(Gogo*);
 
   tree
   do_get_init_tree(Gogo*, tree, bool);
@@ -1717,8 +1717,8 @@ 
   unsigned int
   do_hash_for_method(Gogo*) const;
 
-  tree
-  do_get_tree(Gogo*);
+  Btype*
+  do_get_backend(Gogo*);
 
   tree
   do_get_init_tree(Gogo*, tree, bool);
@@ -1971,8 +1971,8 @@ 
   unsigned int
   do_hash_for_method(Gogo*) const;
 
-  tree
-  do_get_tree(Gogo*);
+  Btype*
+  do_get_backend(Gogo*);
 
   tree
   do_get_init_tree(Gogo*, tree, bool);
@@ -2088,8 +2088,8 @@ 
   bool
   do_check_make_expression(Expression_list*, source_location);
 
-  tree
-  do_get_tree(Gogo*);
+  Btype*
+  do_get_backend(Gogo*);
 
   tree
   do_get_init_tree(Gogo*, tree, bool);
@@ -2179,8 +2179,8 @@ 
   bool
   do_check_make_expression(Expression_list*, source_location);
 
-  tree
-  do_get_tree(Gogo*);
+  Btype*
+  do_get_backend(Gogo*);
 
   tree
   do_get_init_tree(Gogo*, tree, bool);
@@ -2263,8 +2263,8 @@ 
   bool
   do_check_make_expression(Expression_list*, source_location);
 
-  tree
-  do_get_tree(Gogo*);
+  Btype*
+  do_get_backend(Gogo*);
 
   tree
   do_get_init_tree(Gogo*, tree, bool);
@@ -2381,8 +2381,8 @@ 
   unsigned int
   do_hash_for_method(Gogo*) const;
 
-  tree
-  do_get_tree(Gogo*);
+  Btype*
+  do_get_backend(Gogo*);
 
   tree
   do_get_init_tree(Gogo* gogo, tree, bool);
@@ -2612,8 +2612,8 @@ 
   do_check_make_expression(Expression_list* args, source_location location)
   { return this->type_->check_make_expression(args, location); }
 
-  tree
-  do_get_tree(Gogo*);
+  Btype*
+  do_get_backend(Gogo*);
 
   tree
   do_get_init_tree(Gogo* gogo, tree type_tree, bool is_clear)
@@ -2756,8 +2756,8 @@ 
   do_check_make_expression(Expression_list* args, source_location location)
   { return this->base()->check_make_expression(args, location); }
 
-  tree
-  do_get_tree(Gogo* gogo);
+  Btype*
+  do_get_backend(Gogo* gogo);
 
   tree
   do_get_init_tree(Gogo* gogo, tree type_tree, bool is_clear)