// types.cc -- Go frontend types.

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "go-system.h"

#include <ostream>

#include "go-c.h"
#include "gogo.h"
#include "go-diagnostics.h"
#include "go-encode-id.h"
#include "operator.h"
#include "expressions.h"
#include "statements.h"
#include "export.h"
#include "import.h"
#include "backend.h"
#include "types.h"

// Forward declarations so that we don't have to make types.h #include
// backend.h.

static void
get_backend_struct_fields(Gogo* gogo, const Struct_field_list* fields,
			  bool use_placeholder,
			  std::vector<Backend::Btyped_identifier>* bfields);

static void
get_backend_slice_fields(Gogo* gogo, Array_type* type, bool use_placeholder,
			 std::vector<Backend::Btyped_identifier>* bfields);

static void
get_backend_interface_fields(Gogo* gogo, Interface_type* type,
			     bool use_placeholder,
			     std::vector<Backend::Btyped_identifier>* bfields);

// Class Type.

Type::Type(Type_classification classification)
  : classification_(classification), btype_(NULL), type_descriptor_var_(NULL),
    gc_symbol_var_(NULL)
{
}

Type::~Type()
{
}

// Get the base type for a type--skip names and forward declarations.

Type*
Type::base()
{
  switch (this->classification_)
    {
    case TYPE_NAMED:
      return this->named_type()->named_base();
    case TYPE_FORWARD:
      return this->forward_declaration_type()->real_type()->base();
    default:
      return this;
    }
}

const Type*
Type::base() const
{
  switch (this->classification_)
    {
    case TYPE_NAMED:
      return this->named_type()->named_base();
    case TYPE_FORWARD:
      return this->forward_declaration_type()->real_type()->base();
    default:
      return this;
    }
}

// Skip defined forward declarations.

Type*
Type::forwarded()
{
  Type* t = this;
  Forward_declaration_type* ftype = t->forward_declaration_type();
  while (ftype != NULL && ftype->is_defined())
    {
      t = ftype->real_type();
      ftype = t->forward_declaration_type();
    }
  return t;
}

const Type*
Type::forwarded() const
{
  const Type* t = this;
  const Forward_declaration_type* ftype = t->forward_declaration_type();
  while (ftype != NULL && ftype->is_defined())
    {
      t = ftype->real_type();
      ftype = t->forward_declaration_type();
    }
  return t;
}

// Skip alias definitions.

Type*
Type::unalias()
{
  Type* t = this->forwarded();
  Named_type* nt = t->named_type();
  while (nt != NULL && nt->is_alias())
    {
      t = nt->real_type()->forwarded();
      nt = t->named_type();
    }
  return t;
}

const Type*
Type::unalias() const
{
  const Type* t = this->forwarded();
  const Named_type* nt = t->named_type();
  while (nt != NULL && nt->is_alias())
    {
      t = nt->real_type()->forwarded();
      nt = t->named_type();
    }
  return t;
}

// If this is a named type, return it.  Otherwise, return NULL.

Named_type*
Type::named_type()
{
  return this->forwarded()->convert_no_base<Named_type, TYPE_NAMED>();
}

const Named_type*
Type::named_type() const
{
  return this->forwarded()->convert_no_base<const Named_type, TYPE_NAMED>();
}

// Return true if this type is not defined.

bool
Type::is_undefined() const
{
  return this->forwarded()->forward_declaration_type() != NULL;
}

// Return true if this is a basic type: a type which is not composed
// of other types, and is not void.

bool
Type::is_basic_type() const
{
  switch (this->classification_)
    {
    case TYPE_INTEGER:
    case TYPE_FLOAT:
    case TYPE_COMPLEX:
    case TYPE_BOOLEAN:
    case TYPE_STRING:
    case TYPE_NIL:
      return true;

    case TYPE_ERROR:
    case TYPE_VOID:
    case TYPE_FUNCTION:
    case TYPE_POINTER:
    case TYPE_STRUCT:
    case TYPE_ARRAY:
    case TYPE_MAP:
    case TYPE_CHANNEL:
    case TYPE_INTERFACE:
      return false;

    case TYPE_NAMED:
    case TYPE_FORWARD:
      return this->base()->is_basic_type();

    default:
      go_unreachable();
    }
}

// Return true if this is an abstract type.

bool
Type::is_abstract() const
{
  switch (this->classification())
    {
    case TYPE_INTEGER:
      return this->integer_type()->is_abstract();
    case TYPE_FLOAT:
      return this->float_type()->is_abstract();
    case TYPE_COMPLEX:
      return this->complex_type()->is_abstract();
    case TYPE_STRING:
      return this->is_abstract_string_type();
    case TYPE_BOOLEAN:
      return this->is_abstract_boolean_type();
    default:
      return false;
    }
}

// Return a non-abstract version of an abstract type.

Type*
Type::make_non_abstract_type()
{
  go_assert(this->is_abstract());
  switch (this->classification())
    {
    case TYPE_INTEGER:
      if (this->integer_type()->is_rune())
	return Type::lookup_integer_type("int32");
      else
	return Type::lookup_integer_type("int");
    case TYPE_FLOAT:
      return Type::lookup_float_type("float64");
    case TYPE_COMPLEX:
      return Type::lookup_complex_type("complex128");
    case TYPE_STRING:
      return Type::lookup_string_type();
    case TYPE_BOOLEAN:
      return Type::lookup_bool_type();
    default:
      go_unreachable();
    }
}

// Return true if this is an error type.  Don't give an error if we
// try to dereference an undefined forwarding type, as this is called
// in the parser when the type may legitimately be undefined.

bool
Type::is_error_type() const
{
  const Type* t = this->forwarded();
  // Note that we return false for an undefined forward type.
  switch (t->classification_)
    {
    case TYPE_ERROR:
      return true;
    case TYPE_NAMED:
      return t->named_type()->is_named_error_type();
    default:
      return false;
    }
}

// If this is a pointer type, return the type to which it points.
// Otherwise, return NULL.

Type*
Type::points_to() const
{
  const Pointer_type* ptype = this->convert<const Pointer_type,
					    TYPE_POINTER>();
  return ptype == NULL ? NULL : ptype->points_to();
}

// Return whether this is a slice type.

bool
Type::is_slice_type() const
{
  return this->array_type() != NULL && this->array_type()->length() == NULL;
}

// Return whether this is the predeclared constant nil being used as a
// type.

bool
Type::is_nil_constant_as_type() const
{
  const Type* t = this->forwarded();
  if (t->forward_declaration_type() != NULL)
    {
      const Named_object* no = t->forward_declaration_type()->named_object();
      if (no->is_unknown())
	no = no->unknown_value()->real_named_object();
      if (no != NULL
	  && no->is_const()
	  && no->const_value()->expr()->is_nil_expression())
	return true;
    }
  return false;
}

// Traverse a type.

int
Type::traverse(Type* type, Traverse* traverse)
{
  go_assert((traverse->traverse_mask() & Traverse::traverse_types) != 0
	     || (traverse->traverse_mask()
		 & Traverse::traverse_expressions) != 0);
  if (traverse->remember_type(type))
    {
      // We have already traversed this type.
      return TRAVERSE_CONTINUE;
    }
  if ((traverse->traverse_mask() & Traverse::traverse_types) != 0)
    {
      int t = traverse->type(type);
      if (t == TRAVERSE_EXIT)
	return TRAVERSE_EXIT;
      else if (t == TRAVERSE_SKIP_COMPONENTS)
	return TRAVERSE_CONTINUE;
    }
  // An array type has an expression which we need to traverse if
  // traverse_expressions is set.
  if (type->do_traverse(traverse) == TRAVERSE_EXIT)
    return TRAVERSE_EXIT;
  return TRAVERSE_CONTINUE;
}

// Default implementation for do_traverse for child class.

int
Type::do_traverse(Traverse*)
{
  return TRAVERSE_CONTINUE;
}

// Return whether two types are identical.  If REASON is not NULL,
// optionally set *REASON to the reason the types are not identical.

bool
Type::are_identical(const Type* t1, const Type* t2, int flags,
		    std::string* reason)
{
  if (t1 == NULL || t2 == NULL)
    {
      // Something is wrong.
      return (flags & COMPARE_ERRORS) == 0 ? true : t1 == t2;
    }

  // Skip defined forward declarations.  Ignore aliases.
  t1 = t1->unalias();
  t2 = t2->unalias();

  if (t1 == t2)
    return true;

  // An undefined forward declaration is an error.
  if (t1->forward_declaration_type() != NULL
      || t2->forward_declaration_type() != NULL)
    return (flags & COMPARE_ERRORS) == 0;

  // Avoid cascading errors with error types.
  if (t1->is_error_type() || t2->is_error_type())
    {
      if ((flags & COMPARE_ERRORS) == 0)
	return true;
      return t1->is_error_type() && t2->is_error_type();
    }

  // Get a good reason for the sink type.  Note that the sink type on
  // the left hand side of an assignment is handled in are_assignable.
  if (t1->is_sink_type() || t2->is_sink_type())
    {
      if (reason != NULL)
	*reason = "invalid use of _";
      return false;
    }

  // A named type is only identical to itself.
  if (t1->named_type() != NULL || t2->named_type() != NULL)
    return false;

  // Check type shapes.
  if (t1->classification() != t2->classification())
    return false;

  switch (t1->classification())
    {
    case TYPE_VOID:
    case TYPE_BOOLEAN:
    case TYPE_STRING:
    case TYPE_NIL:
      // These types are always identical.
      return true;

    case TYPE_INTEGER:
      return t1->integer_type()->is_identical(t2->integer_type());

    case TYPE_FLOAT:
      return t1->float_type()->is_identical(t2->float_type());

    case TYPE_COMPLEX:
      return t1->complex_type()->is_identical(t2->complex_type());

    case TYPE_FUNCTION:
      return t1->function_type()->is_identical(t2->function_type(),
					       false, flags, reason);

    case TYPE_POINTER:
      return Type::are_identical(t1->points_to(), t2->points_to(), flags,
				 reason);

    case TYPE_STRUCT:
      return t1->struct_type()->is_identical(t2->struct_type(), flags);

    case TYPE_ARRAY:
      return t1->array_type()->is_identical(t2->array_type(), flags);

    case TYPE_MAP:
      return t1->map_type()->is_identical(t2->map_type(), flags);

    case TYPE_CHANNEL:
      return t1->channel_type()->is_identical(t2->channel_type(), flags);

    case TYPE_INTERFACE:
      return t1->interface_type()->is_identical(t2->interface_type(), flags);

    case TYPE_CALL_MULTIPLE_RESULT:
      if (reason != NULL)
	*reason = "invalid use of multiple-value function call";
      return false;

    default:
      go_unreachable();
    }
}

// Return true if it's OK to have a binary operation with types LHS
// and RHS.  This is not used for shifts or comparisons.

bool
Type::are_compatible_for_binop(const Type* lhs, const Type* rhs)
{
  if (Type::are_identical(lhs, rhs, Type::COMPARE_TAGS, NULL))
    return true;

  // A constant of abstract bool type may be mixed with any bool type.
  if ((rhs->is_abstract_boolean_type() && lhs->is_boolean_type())
      || (lhs->is_abstract_boolean_type() && rhs->is_boolean_type()))
    return true;

  // A constant of abstract string type may be mixed with any string
  // type.
  if ((rhs->is_abstract_string_type() && lhs->is_string_type())
      || (lhs->is_abstract_string_type() && rhs->is_string_type()))
    return true;

  lhs = lhs->base();
  rhs = rhs->base();

  // A constant of abstract integer, float, or complex type may be
  // mixed with an integer, float, or complex type.
  if ((rhs->is_abstract()
       && (rhs->integer_type() != NULL
	   || rhs->float_type() != NULL
	   || rhs->complex_type() != NULL)
       && (lhs->integer_type() != NULL
	   || lhs->float_type() != NULL
	   || lhs->complex_type() != NULL))
      || (lhs->is_abstract()
	  && (lhs->integer_type() != NULL
	      || lhs->float_type() != NULL
	      || lhs->complex_type() != NULL)
	  && (rhs->integer_type() != NULL
	      || rhs->float_type() != NULL
	      || rhs->complex_type() != NULL)))
    return true;

  // The nil type may be compared to a pointer, an interface type, a
  // slice type, a channel type, a map type, or a function type.
  if (lhs->is_nil_type()
      && (rhs->points_to() != NULL
	  || rhs->interface_type() != NULL
	  || rhs->is_slice_type()
	  || rhs->map_type() != NULL
	  || rhs->channel_type() != NULL
	  || rhs->function_type() != NULL))
    return true;
  if (rhs->is_nil_type()
      && (lhs->points_to() != NULL
	  || lhs->interface_type() != NULL
	  || lhs->is_slice_type()
	  || lhs->map_type() != NULL
	  || lhs->channel_type() != NULL
	  || lhs->function_type() != NULL))
    return true;

  return false;
}

// Return true if a value with type T1 may be compared with a value of
// type T2.  IS_EQUALITY_OP is true for == or !=, false for <, etc.

bool
Type::are_compatible_for_comparison(bool is_equality_op, const Type *t1,
				    const Type *t2, std::string *reason)
{
  if (t1 != t2
      && !Type::are_assignable(t1, t2, NULL)
      && !Type::are_assignable(t2, t1, NULL))
    {
      if (reason != NULL)
	*reason = "incompatible types in binary expression";
      return false;
    }

  if (!is_equality_op)
    {
      if (t1->integer_type() == NULL
	  && t1->float_type() == NULL
	  && !t1->is_string_type())
	{
	  if (reason != NULL)
	    *reason = _("invalid comparison of non-ordered type");
	  return false;
	}
    }
  else if (t1->is_slice_type()
	   || t1->map_type() != NULL
	   || t1->function_type() != NULL
	   || t2->is_slice_type()
	   || t2->map_type() != NULL
	   || t2->function_type() != NULL)
    {
      if (!t1->is_nil_type() && !t2->is_nil_type())
	{
	  if (reason != NULL)
	    {
	      if (t1->is_slice_type() || t2->is_slice_type())
		*reason = _("slice can only be compared to nil");
	      else if (t1->map_type() != NULL || t2->map_type() != NULL)
		*reason = _("map can only be compared to nil");
	      else
		*reason = _("func can only be compared to nil");

	      // Match 6g error messages.
	      if (t1->interface_type() != NULL || t2->interface_type() != NULL)
		{
		  char buf[200];
		  snprintf(buf, sizeof buf, _("invalid operation (%s)"),
			   reason->c_str());
		  *reason = buf;
		}
	    }
	  return false;
	}
    }
  else
    {
      if (!t1->is_boolean_type()
	  && t1->integer_type() == NULL
	  && t1->float_type() == NULL
	  && t1->complex_type() == NULL
	  && !t1->is_string_type()
	  && t1->points_to() == NULL
	  && t1->channel_type() == NULL
	  && t1->interface_type() == NULL
	  && t1->struct_type() == NULL
	  && t1->array_type() == NULL
	  && !t1->is_nil_type())
	{
	  if (reason != NULL)
	    *reason = _("invalid comparison of non-comparable type");
	  return false;
	}

      if (t1->unalias()->named_type() != NULL)
	return t1->unalias()->named_type()->named_type_is_comparable(reason);
      else if (t2->unalias()->named_type() != NULL)
	return t2->unalias()->named_type()->named_type_is_comparable(reason);
      else if (t1->struct_type() != NULL)
	{
	  if (t1->struct_type()->is_struct_incomparable())
	    {
	      if (reason != NULL)
		*reason = _("invalid comparison of generated struct");
	      return false;
	    }
	  const Struct_field_list* fields = t1->struct_type()->fields();
	  for (Struct_field_list::const_iterator p = fields->begin();
	       p != fields->end();
	       ++p)
	    {
	      if (!p->type()->is_comparable())
		{
		  if (reason != NULL)
		    *reason = _("invalid comparison of non-comparable struct");
		  return false;
		}
	    }
	}
      else if (t1->array_type() != NULL)
	{
	  if (t1->array_type()->is_array_incomparable())
	    {
	      if (reason != NULL)
		*reason = _("invalid comparison of generated array");
	      return false;
	    }
	  if (t1->array_type()->length()->is_nil_expression()
	      || !t1->array_type()->element_type()->is_comparable())
	    {
	      if (reason != NULL)
		*reason = _("invalid comparison of non-comparable array");
	      return false;
	    }
	}
    }

  return true;
}

// Return true if a value with type RHS may be assigned to a variable
// with type LHS.  If REASON is not NULL, set *REASON to the reason
// the types are not assignable.

bool
Type::are_assignable(const Type* lhs, const Type* rhs, std::string* reason)
{
  // Do some checks first.  Make sure the types are defined.
  if (rhs != NULL && !rhs->is_undefined())
    {
      if (rhs->is_void_type())
	{
	  if (reason != NULL)
	    *reason = "non-value used as value";
	  return false;
	}
      if (rhs->is_call_multiple_result_type())
	{
	  if (reason != NULL)
	    reason->assign(_("multiple-value function call in "
			     "single-value context"));
	  return false;
	}
    }

  // Any value may be assigned to the blank identifier.
  if (lhs != NULL
      && !lhs->is_undefined()
      && lhs->is_sink_type())
    return true;

  // Identical types are assignable.
  if (Type::are_identical(lhs, rhs, Type::COMPARE_TAGS, reason))
    return true;

  // Ignore aliases, except for error messages.
  const Type* lhs_orig = lhs;
  const Type* rhs_orig = rhs;
  lhs = lhs->unalias();
  rhs = rhs->unalias();

  // The types are assignable if they have identical underlying types
  // and either LHS or RHS is not a named type.
  if (((lhs->named_type() != NULL && rhs->named_type() == NULL)
       || (rhs->named_type() != NULL && lhs->named_type() == NULL))
      && Type::are_identical(lhs->base(), rhs->base(), Type::COMPARE_TAGS,
			     reason))
    return true;

  // The types are assignable if LHS is an interface type and RHS
  // implements the required methods.
  const Interface_type* lhs_interface_type = lhs->interface_type();
  if (lhs_interface_type != NULL)
    {
      if (lhs_interface_type->implements_interface(rhs, reason))
	return true;
      const Interface_type* rhs_interface_type = rhs->interface_type();
      if (rhs_interface_type != NULL
	  && lhs_interface_type->is_compatible_for_assign(rhs_interface_type,
							  reason))
	return true;
    }

  // The type are assignable if RHS is a bidirectional channel type,
  // LHS is a channel type, they have identical element types, and
  // either LHS or RHS is not a named type.
  if (lhs->channel_type() != NULL
      && rhs->channel_type() != NULL
      && rhs->channel_type()->may_send()
      && rhs->channel_type()->may_receive()
      && (lhs->named_type() == NULL || rhs->named_type() == NULL)
      && Type::are_identical(lhs->channel_type()->element_type(),
			     rhs->channel_type()->element_type(),
			     Type::COMPARE_TAGS,
			     reason))
    return true;

  // The nil type may be assigned to a pointer, function, slice, map,
  // channel, or interface type.
  if (rhs->is_nil_type()
      && (lhs->points_to() != NULL
	  || lhs->function_type() != NULL
	  || lhs->is_slice_type()
	  || lhs->map_type() != NULL
	  || lhs->channel_type() != NULL
	  || lhs->interface_type() != NULL))
    return true;

  // An untyped numeric constant may be assigned to a numeric type if
  // it is representable in that type.
  if ((rhs->is_abstract()
       && (rhs->integer_type() != NULL
	   || rhs->float_type() != NULL
	   || rhs->complex_type() != NULL))
      && (lhs->integer_type() != NULL
	  || lhs->float_type() != NULL
	  || lhs->complex_type() != NULL))
    return true;

  // Give some better error messages.
  if (reason != NULL && reason->empty())
    {
      if (rhs->interface_type() != NULL)
	reason->assign(_("need explicit conversion"));
      else if (lhs_orig->named_type() != NULL
	       && rhs_orig->named_type() != NULL)
	{
	  size_t len = (lhs_orig->named_type()->name().length()
			+ rhs_orig->named_type()->name().length()
			+ 100);
	  char* buf = new char[len];
	  snprintf(buf, len, _("cannot use type %s as type %s"),
		   rhs_orig->named_type()->message_name().c_str(),
		   lhs_orig->named_type()->message_name().c_str());
	  reason->assign(buf);
	  delete[] buf;
	}
    }

  return false;
}

// Return true if a value with type RHS may be converted to type LHS.
// If REASON is not NULL, set *REASON to the reason the types are not
// convertible.

bool
Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason)
{
  // The types are convertible if they are assignable.
  if (Type::are_assignable(lhs, rhs, reason))
    return true;

  // Ignore aliases.
  lhs = lhs->unalias();
  rhs = rhs->unalias();

  // A pointer to a regular type may not be converted to a pointer to
  // a type that may not live in the heap, except when converting from
  // unsafe.Pointer.
  if (lhs->points_to() != NULL
      && rhs->points_to() != NULL
      && !lhs->points_to()->in_heap()
      && rhs->points_to()->in_heap()
      && !rhs->is_unsafe_pointer_type())
    {
      if (reason != NULL)
	reason->assign(_("conversion from normal type to notinheap type"));
      return false;
    }

  // The types are convertible if they have identical underlying
  // types, ignoring struct field tags.
  if ((lhs->named_type() != NULL || rhs->named_type() != NULL)
      && Type::are_identical(lhs->base(), rhs->base(), 0, reason))
    return true;

  // The types are convertible if they are both unnamed pointer types
  // and their pointer base types have identical underlying types,
  // ignoring struct field tags.
  if (lhs->named_type() == NULL
      && rhs->named_type() == NULL
      && lhs->points_to() != NULL
      && rhs->points_to() != NULL
      && (lhs->points_to()->named_type() != NULL
	  || rhs->points_to()->named_type() != NULL)
      && Type::are_identical(lhs->points_to()->base(),
			     rhs->points_to()->base(),
			     0, reason))
    return true;

  // Integer and floating point types are convertible to each other.
  if ((lhs->integer_type() != NULL || lhs->float_type() != NULL)
      && (rhs->integer_type() != NULL || rhs->float_type() != NULL))
    return true;

  // Complex types are convertible to each other.
  if (lhs->complex_type() != NULL && rhs->complex_type() != NULL)
    return true;

  // An integer, or []byte, or []rune, may be converted to a string.
  if (lhs->is_string_type())
    {
      if (rhs->integer_type() != NULL)
	return true;
      if (rhs->is_slice_type())
	{
	  const Type* e = rhs->array_type()->element_type()->forwarded();
	  if (e->integer_type() != NULL
	      && (e->integer_type()->is_byte()
		  || e->integer_type()->is_rune()))
	    return true;
	}
    }

  // A string may be converted to []byte or []rune.
  if (rhs->is_string_type() && lhs->is_slice_type())
    {
      const Type* e = lhs->array_type()->element_type()->forwarded();
      if (e->integer_type() != NULL
	  && (e->integer_type()->is_byte() || e->integer_type()->is_rune()))
	return true;
    }

  // An unsafe.Pointer type may be converted to any pointer type or to
  // a type whose underlying type is uintptr, and vice-versa.
  if (lhs->is_unsafe_pointer_type()
      && (rhs->points_to() != NULL
	  || (rhs->integer_type() != NULL
	      && rhs->integer_type() == Type::lookup_integer_type("uintptr")->real_type())))
    return true;
  if (rhs->is_unsafe_pointer_type()
      && (lhs->points_to() != NULL
	  || (lhs->integer_type() != NULL
	      && lhs->integer_type() == Type::lookup_integer_type("uintptr")->real_type())))
    return true;

  // Give a better error message.
  if (reason != NULL)
    {
      if (reason->empty())
	*reason = "invalid type conversion";
      else
	{
	  std::string s = "invalid type conversion (";
	  s += *reason;
	  s += ')';
	  *reason = s;
	}
    }

  return false;
}

// Copy expressions if it may change the size.
//
// The only type that has an expression is an array type.  The only
// types whose size can be changed by the size of an array type are an
// array type itself, or a struct type with an array field.
Type*
Type::copy_expressions()
{
  // This is run during parsing, so types may not be valid yet.
  // We only have to worry about array type literals.
  switch (this->classification_)
    {
    default:
      return this;

    case TYPE_ARRAY:
      {
	Array_type* at = this->array_type();
	if (at->length() == NULL)
	  return this;
	Expression* len = at->length()->copy();
	if (at->length() == len)
	  return this;
	return Type::make_array_type(at->element_type(), len);
      }

    case TYPE_STRUCT:
      {
	Struct_type* st = this->struct_type();
	const Struct_field_list* sfl = st->fields();
	if (sfl == NULL)
	  return this;
	bool changed = false;
	Struct_field_list *nsfl = new Struct_field_list();
	for (Struct_field_list::const_iterator pf = sfl->begin();
	     pf != sfl->end();
	     ++pf)
	  {
	    Type* ft = pf->type()->copy_expressions();
	    Struct_field nf(Typed_identifier((pf->is_anonymous()
					      ? ""
					      : pf->field_name()),
					     ft,
					     pf->location()));
	    if (pf->has_tag())
	      nf.set_tag(pf->tag());
	    nsfl->push_back(nf);
	    if (ft != pf->type())
	      changed = true;
	  }
	if (!changed)
	  {
	    delete(nsfl);
	    return this;
	  }
	return Type::make_struct_type(nsfl, st->location());
      }
    }

  go_unreachable();
}

// Return a hash code for the type to be used for method lookup.

unsigned int
Type::hash_for_method(Gogo* gogo, int flags) const
{
  if (this->named_type() != NULL && this->named_type()->is_alias())
    return this->named_type()->real_type()->hash_for_method(gogo, flags);
  unsigned int ret = 0;
  if (this->classification_ != TYPE_FORWARD)
    ret += this->classification_;
  return ret + this->do_hash_for_method(gogo, flags);
}

// Default implementation of do_hash_for_method.  This is appropriate
// for types with no subfields.

unsigned int
Type::do_hash_for_method(Gogo*, int) const
{
  return 0;
}

// Return a hash code for a string, given a starting hash.

unsigned int
Type::hash_string(const std::string& s, unsigned int h)
{
  const char* p = s.data();
  size_t len = s.length();
  for (; len > 0; --len)
    {
      h ^= *p++;
      h*= 16777619;
    }
  return h;
}

// A hash table mapping unnamed types to the backend representation of
// those types.

Type::Type_btypes Type::type_btypes;

// Return the backend representation for this type.

Btype*
Type::get_backend(Gogo* gogo)
{
  if (this->btype_ != NULL)
    return this->btype_;

  if (this->named_type() != NULL && this->named_type()->is_alias()) {
    Btype* bt = this->unalias()->get_backend(gogo);
    if (gogo != NULL && gogo->named_types_are_converted())
      this->btype_ = bt;
    return bt;
  }

  if (this->forward_declaration_type() != NULL
      || this->named_type() != NULL)
    return this->get_btype_without_hash(gogo);

  if (this->is_error_type())
    return gogo->backend()->error_type();

  // To avoid confusing the backend, translate all identical Go types
  // 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*, Type_btype_entry> val;
  val.first = this;
  val.second.btype = NULL;
  val.second.is_placeholder = false;
  std::pair<Type_btypes::iterator, bool> ins =
    Type::type_btypes.insert(val);
  if (!ins.second && ins.first->second.btype != NULL)
    {
      // Note that GOGO can be NULL here, but only when the GCC
      // middle-end is asking for a frontend type.  That will only
      // happen for simple types, which should never require
      // placeholders.
      if (!ins.first->second.is_placeholder)
	this->btype_ = ins.first->second.btype;
      else if (gogo->named_types_are_converted())
	{
	  this->finish_backend(gogo, ins.first->second.btype);
	  ins.first->second.is_placeholder = false;
	}

      return ins.first->second.btype;
    }

  Btype* bt = this->get_btype_without_hash(gogo);

  if (ins.first->second.btype == NULL)
    {
      ins.first->second.btype = bt;
      ins.first->second.is_placeholder = false;
    }
  else
    {
      // 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 representation we created earlier and ignore the one we just
      // built.
      if (this->btype_ == bt)
	this->btype_ = ins.first->second.btype;
      bt = ins.first->second.btype;
    }

  return bt;
}

// Return the backend representation for a type without looking in the
// hash table for identical types.  This is used for named types,
// since a named type is never identical to any other type.

Btype*
Type::get_btype_without_hash(Gogo* 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
      // don't want to record that for a forwarding type, as it may
      // confuse us later.
      if (this->forward_declaration_type() != NULL
	  && gogo->backend()->is_circular_pointer_type(bt))
	return bt;

      if (gogo == NULL || !gogo->named_types_are_converted())
	return bt;

      this->btype_ = bt;
    }
  return this->btype_;
}

// Get the backend representation of a type without forcing the
// creation of the backend representation of all supporting types.
// This will return a backend type that has the correct size but may
// be incomplete.  E.g., a pointer will just be a placeholder pointer,
// and will not contain the final representation of the type to which
// it points.  This is used while converting all named types to the
// backend representation, to avoid problems with indirect references
// to types which are not yet complete.  When this is called, the
// sizes of all direct references (e.g., a struct field) should be
// known, but the sizes of indirect references (e.g., the type to
// which a pointer points) may not.

Btype*
Type::get_backend_placeholder(Gogo* gogo)
{
  if (gogo->named_types_are_converted())
    return this->get_backend(gogo);
  if (this->btype_ != NULL)
    return this->btype_;

  Btype* bt;
  switch (this->classification_)
    {
    case TYPE_ERROR:
    case TYPE_VOID:
    case TYPE_BOOLEAN:
    case TYPE_INTEGER:
    case TYPE_FLOAT:
    case TYPE_COMPLEX:
    case TYPE_STRING:
    case TYPE_NIL:
      // These are simple types that can just be created directly.
      return this->get_backend(gogo);

    case TYPE_MAP:
    case TYPE_CHANNEL:
      // All maps and channels have the same backend representation.
      return this->get_backend(gogo);

    case TYPE_NAMED:
    case TYPE_FORWARD:
      // Named types keep track of their own dependencies and manage
      // their own placeholders.
      if (this->named_type() != NULL && this->named_type()->is_alias())
        return this->unalias()->get_backend_placeholder(gogo);
      return this->get_backend(gogo);

    case TYPE_INTERFACE:
      if (this->interface_type()->is_empty())
	return Interface_type::get_backend_empty_interface_type(gogo);
      break;

    default:
      break;
    }

  std::pair<Type*, Type_btype_entry> val;
  val.first = this;
  val.second.btype = NULL;
  val.second.is_placeholder = false;
  std::pair<Type_btypes::iterator, bool> ins =
    Type::type_btypes.insert(val);
  if (!ins.second && ins.first->second.btype != NULL)
    return ins.first->second.btype;

  switch (this->classification_)
    {
    case TYPE_FUNCTION:
      {
	// A Go function type is a pointer to a struct type.
	Location loc = this->function_type()->location();
	bt = gogo->backend()->placeholder_pointer_type("", loc, false);
      }
      break;

    case TYPE_POINTER:
      {
	Location loc = Linemap::unknown_location();
	bt = gogo->backend()->placeholder_pointer_type("", loc, false);
	Pointer_type* pt = this->convert<Pointer_type, TYPE_POINTER>();
	Type::placeholder_pointers.push_back(pt);
      }
      break;

    case TYPE_STRUCT:
      // We don't have to make the struct itself be a placeholder.  We
      // are promised that we know the sizes of the struct fields.
      // But we may have to use a placeholder for any particular
      // struct field.
      {
	std::vector<Backend::Btyped_identifier> bfields;
	get_backend_struct_fields(gogo, this->struct_type()->fields(),
				  true, &bfields);
	bt = gogo->backend()->struct_type(bfields);
      }
      break;

    case TYPE_ARRAY:
      if (this->is_slice_type())
	{
	  std::vector<Backend::Btyped_identifier> bfields;
	  get_backend_slice_fields(gogo, this->array_type(), true, &bfields);
	  bt = gogo->backend()->struct_type(bfields);
	}
      else
	{
	  Btype* element = this->array_type()->get_backend_element(gogo, true);
	  Bexpression* len = this->array_type()->get_backend_length(gogo);
	  bt = gogo->backend()->array_type(element, len);
	}
      break;
	
    case TYPE_INTERFACE:
      {
	go_assert(!this->interface_type()->is_empty());
	std::vector<Backend::Btyped_identifier> bfields;
	get_backend_interface_fields(gogo, this->interface_type(), true,
				     &bfields);
	bt = gogo->backend()->struct_type(bfields);
      }
      break;

    case TYPE_SINK:
    case TYPE_CALL_MULTIPLE_RESULT:
      /* Note that various classifications were handled in the earlier
	 switch.  */
    default:
      go_unreachable();
    }

  if (ins.first->second.btype == NULL)
    {
      ins.first->second.btype = bt;
      ins.first->second.is_placeholder = true;
    }
  else
    {
      // A placeholder for this type got created along the way.  Use
      // that one and ignore the one we just built.
      bt = ins.first->second.btype;
    }

  return bt;
}

// Complete the backend representation.  This is called for a type
// using a placeholder type.

void
Type::finish_backend(Gogo* gogo, Btype *placeholder)
{
  switch (this->classification_)
    {
    case TYPE_ERROR:
    case TYPE_VOID:
    case TYPE_BOOLEAN:
    case TYPE_INTEGER:
    case TYPE_FLOAT:
    case TYPE_COMPLEX:
    case TYPE_STRING:
    case TYPE_NIL:
      go_unreachable();

    case TYPE_FUNCTION:
      {
	Btype* bt = this->do_get_backend(gogo);
	if (!gogo->backend()->set_placeholder_pointer_type(placeholder, bt))
	  go_assert(saw_errors());
      }
      break;

    case TYPE_POINTER:
      {
	Btype* bt = this->do_get_backend(gogo);
	if (!gogo->backend()->set_placeholder_pointer_type(placeholder, bt))
	  go_assert(saw_errors());
      }
      break;

    case TYPE_STRUCT:
      // The struct type itself is done, but we have to make sure that
      // all the field types are converted.
      this->struct_type()->finish_backend_fields(gogo);
      break;

    case TYPE_ARRAY:
      // The array type itself is done, but make sure the element type
      // is converted.
      this->array_type()->finish_backend_element(gogo);
      break;
	
    case TYPE_MAP:
    case TYPE_CHANNEL:
      go_unreachable();

    case TYPE_INTERFACE:
      // The interface type itself is done, but make sure the method
      // types are converted.
      this->interface_type()->finish_backend_methods(gogo);
      break;

    case TYPE_NAMED:
    case TYPE_FORWARD:
      go_unreachable();

    case TYPE_SINK:
    case TYPE_CALL_MULTIPLE_RESULT:
    default:
      go_unreachable();
    }

  this->btype_ = placeholder;
}

// Return a pointer to the type descriptor for this type.

Bexpression*
Type::type_descriptor_pointer(Gogo* gogo, Location location)
{
  Type* t = this->unalias();
  if (t->type_descriptor_var_ == NULL)
    {
      t->make_type_descriptor_var(gogo);
      go_assert(t->type_descriptor_var_ != NULL);
    }
  Bexpression* var_expr =
      gogo->backend()->var_expression(t->type_descriptor_var_, location);
  Bexpression* var_addr =
      gogo->backend()->address_expression(var_expr, location);
  Type* td_type = Type::make_type_descriptor_type();
  Btype* td_btype = td_type->get_backend(gogo);
  Btype* ptd_btype = gogo->backend()->pointer_type(td_btype);
  return gogo->backend()->convert_expression(ptd_btype, var_addr, location);
}

// A mapping from unnamed types to type descriptor variables.

Type::Type_descriptor_vars Type::type_descriptor_vars;

// Build the type descriptor for this type.

void
Type::make_type_descriptor_var(Gogo* gogo)
{
  go_assert(this->type_descriptor_var_ == NULL);

  Named_type* nt = this->named_type();

  // We can have multiple instances of unnamed types, but we only want
  // to emit the type descriptor once.  We use a hash table.  This is
  // not necessary for named types, as they are unique, and we store
  // the type descriptor in the type itself.
  Bvariable** phash = NULL;
  if (nt == NULL)
    {
      Bvariable* bvnull = NULL;
      std::pair<Type_descriptor_vars::iterator, bool> ins =
	Type::type_descriptor_vars.insert(std::make_pair(this, bvnull));
      if (!ins.second)
	{
	  // We've already built a type descriptor for this type.
	  this->type_descriptor_var_ = ins.first->second;
	  return;
	}
      phash = &ins.first->second;
    }

  // The type descriptor symbol for the unsafe.Pointer type is defined in
  // libgo/go-unsafe-pointer.c, so we just return a reference to that
  // symbol if necessary.
  if (this->is_unsafe_pointer_type())
    {
      Location bloc = Linemap::predeclared_location();

      Type* td_type = Type::make_type_descriptor_type();
      Btype* td_btype = td_type->get_backend(gogo);
      std::string name = gogo->type_descriptor_name(this, nt);
      std::string asm_name(go_selectively_encode_id(name));
      this->type_descriptor_var_ =
	  gogo->backend()->immutable_struct_reference(name, asm_name,
						      td_btype,
						      bloc);

      if (phash != NULL)
	*phash = this->type_descriptor_var_;
      return;
    }

  std::string var_name = gogo->type_descriptor_name(this, nt);

  // Build the contents of the type descriptor.
  Expression* initializer = this->do_type_descriptor(gogo, NULL);

  Btype* initializer_btype = initializer->type()->get_backend(gogo);

  Location loc = nt == NULL ? Linemap::predeclared_location() : nt->location();

  const Package* dummy;
  if (this->type_descriptor_defined_elsewhere(nt, &dummy))
    {
      std::string asm_name(go_selectively_encode_id(var_name));
      this->type_descriptor_var_ =
	  gogo->backend()->immutable_struct_reference(var_name, asm_name,
						      initializer_btype,
						      loc);
      if (phash != NULL)
	*phash = this->type_descriptor_var_;
      return;
    }

  // See if this type descriptor can appear in multiple packages.
  bool is_common = false;
  if (nt != NULL)
    {
      // We create the descriptor for a builtin type whenever we need
      // it.
      is_common = nt->is_builtin();
    }
  else
    {
      // This is an unnamed type.  The descriptor could be defined in
      // any package where it is needed, and the linker will pick one
      // descriptor to keep.
      is_common = true;
    }

  // We are going to build the type descriptor in this package.  We
  // must create the variable before we convert the initializer to the
  // backend representation, because the initializer may refer to the
  // type descriptor of this type.  By setting type_descriptor_var_ we
  // ensure that type_descriptor_pointer will work if called while
  // converting INITIALIZER.

  std::string asm_name(go_selectively_encode_id(var_name));
  this->type_descriptor_var_ =
      gogo->backend()->immutable_struct(var_name, asm_name, false, is_common,
				      initializer_btype, loc);
  if (phash != NULL)
    *phash = this->type_descriptor_var_;

  Translate_context context(gogo, NULL, NULL, NULL);
  context.set_is_const();
  Bexpression* binitializer = initializer->get_backend(&context);

  gogo->backend()->immutable_struct_set_init(this->type_descriptor_var_,
					     var_name, false, is_common,
					     initializer_btype, loc,
					     binitializer);
}

// Return true if this type descriptor is defined in a different
// package.  If this returns true it sets *PACKAGE to the package.

bool
Type::type_descriptor_defined_elsewhere(Named_type* nt,
					const Package** package)
{
  if (nt != NULL)
    {
      if (nt->named_object()->package() != NULL)
	{
	  // This is a named type defined in a different package.  The
	  // type descriptor should be defined in that package.
	  *package = nt->named_object()->package();
	  return true;
	}
    }
  else
    {
      if (this->points_to() != NULL
	  && this->points_to()->named_type() != NULL
	  && this->points_to()->named_type()->named_object()->package() != NULL)
	{
	  // This is an unnamed pointer to a named type defined in a
	  // different package.  The descriptor should be defined in
	  // that package.
	  *package = this->points_to()->named_type()->named_object()->package();
	  return true;
	}
    }
  return false;
}

// Return a composite literal for a type descriptor.

Expression*
Type::type_descriptor(Gogo* gogo, Type* type)
{
  return type->do_type_descriptor(gogo, NULL);
}

// Return a composite literal for a type descriptor with a name.

Expression*
Type::named_type_descriptor(Gogo* gogo, Type* type, Named_type* name)
{
  go_assert(name != NULL && type->named_type() != name);
  return type->do_type_descriptor(gogo, name);
}

// Make a builtin struct type from a list of fields.  The fields are
// pairs of a name and a type.

Struct_type*
Type::make_builtin_struct_type(int nfields, ...)
{
  va_list ap;
  va_start(ap, nfields);

  Location bloc = Linemap::predeclared_location();
  Struct_field_list* sfl = new Struct_field_list();
  for (int i = 0; i < nfields; i++)
    {
      const char* field_name = va_arg(ap, const char *);
      Type* type = va_arg(ap, Type*);
      sfl->push_back(Struct_field(Typed_identifier(field_name, type, bloc)));
    }

  va_end(ap);

  Struct_type* ret = Type::make_struct_type(sfl, bloc);
  ret->set_is_struct_incomparable();
  return ret;
}

// A list of builtin named types.

std::vector<Named_type*> Type::named_builtin_types;

// Make a builtin named type.

Named_type*
Type::make_builtin_named_type(const char* name, Type* type)
{
  Location bloc = Linemap::predeclared_location();
  Named_object* no = Named_object::make_type(name, NULL, type, bloc);
  Named_type* ret = no->type_value();
  Type::named_builtin_types.push_back(ret);
  return ret;
}

// Convert the named builtin types.

void
Type::convert_builtin_named_types(Gogo* gogo)
{
  for (std::vector<Named_type*>::const_iterator p =
	 Type::named_builtin_types.begin();
       p != Type::named_builtin_types.end();
       ++p)
    {
      bool r = (*p)->verify();
      go_assert(r);
      (*p)->convert(gogo);
    }
}

// Return the type of a type descriptor.  We should really tie this to
// runtime.Type rather than copying it.  This must match the struct "_type"
// declared in libgo/go/runtime/type.go.

Type*
Type::make_type_descriptor_type()
{
  static Type* ret;
  if (ret == NULL)
    {
      Location bloc = Linemap::predeclared_location();

      Type* uint8_type = Type::lookup_integer_type("uint8");
      Type* pointer_uint8_type = Type::make_pointer_type(uint8_type);
      Type* uint32_type = Type::lookup_integer_type("uint32");
      Type* uintptr_type = Type::lookup_integer_type("uintptr");
      Type* string_type = Type::lookup_string_type();
      Type* pointer_string_type = Type::make_pointer_type(string_type);

      // This is an unnamed version of unsafe.Pointer.  Perhaps we
      // should use the named version instead, although that would
      // require us to create the unsafe package if it has not been
      // imported.  It probably doesn't matter.
      Type* void_type = Type::make_void_type();
      Type* unsafe_pointer_type = Type::make_pointer_type(void_type);

      Typed_identifier_list *params = new Typed_identifier_list();
      params->push_back(Typed_identifier("key", unsafe_pointer_type, bloc));
      params->push_back(Typed_identifier("seed", uintptr_type, bloc));

      Typed_identifier_list* results = new Typed_identifier_list();
      results->push_back(Typed_identifier("", uintptr_type, bloc));

      Type* hash_fntype = Type::make_function_type(NULL, params, results,
						   bloc);

      params = new Typed_identifier_list();
      params->push_back(Typed_identifier("key1", unsafe_pointer_type, bloc));
      params->push_back(Typed_identifier("key2", unsafe_pointer_type, bloc));

      results = new Typed_identifier_list();
      results->push_back(Typed_identifier("", Type::lookup_bool_type(), bloc));

      Type* equal_fntype = Type::make_function_type(NULL, params, results,
						    bloc);

      // Forward declaration for the type descriptor type.
      Named_object* named_type_descriptor_type =
	Named_object::make_type_declaration("_type", NULL, bloc);
      Type* ft = Type::make_forward_declaration(named_type_descriptor_type);
      Type* pointer_type_descriptor_type = Type::make_pointer_type(ft);

      // The type of a method on a concrete type.
      Struct_type* method_type =
	Type::make_builtin_struct_type(5,
				       "name", pointer_string_type,
				       "pkgPath", pointer_string_type,
				       "mtyp", pointer_type_descriptor_type,
				       "typ", pointer_type_descriptor_type,
				       "tfn", unsafe_pointer_type);
      Named_type* named_method_type =
	Type::make_builtin_named_type("method", method_type);

      // Information for types with a name or methods.
      Type* slice_named_method_type =
	Type::make_array_type(named_method_type, NULL);
      Struct_type* uncommon_type =
	Type::make_builtin_struct_type(3,
				       "name", pointer_string_type,
				       "pkgPath", pointer_string_type,
				       "methods", slice_named_method_type);
      Named_type* named_uncommon_type =
	Type::make_builtin_named_type("uncommonType", uncommon_type);

      Type* pointer_uncommon_type =
	Type::make_pointer_type(named_uncommon_type);

      // The type descriptor type.

      Struct_type* type_descriptor_type =
	Type::make_builtin_struct_type(12,
				       "size", uintptr_type,
				       "ptrdata", uintptr_type,
				       "hash", uint32_type,
				       "kind", uint8_type,
				       "align", uint8_type,
				       "fieldAlign", uint8_type,
				       "hashfn", hash_fntype,
				       "equalfn", equal_fntype,
				       "gcdata", pointer_uint8_type,
				       "string", pointer_string_type,
				       "", pointer_uncommon_type,
				       "ptrToThis",
				       pointer_type_descriptor_type);

      Named_type* named = Type::make_builtin_named_type("_type",
							type_descriptor_type);

      named_type_descriptor_type->set_type_value(named);

      ret = named;
    }

  return ret;
}

// Make the type of a pointer to a type descriptor as represented in
// Go.

Type*
Type::make_type_descriptor_ptr_type()
{
  static Type* ret;
  if (ret == NULL)
    ret = Type::make_pointer_type(Type::make_type_descriptor_type());
  return ret;
}

// Return the alignment required by the memequalN function.  N is a
// type size: 16, 32, 64, or 128.  The memequalN functions are defined
// in libgo/go/runtime/alg.go.

int64_t
Type::memequal_align(Gogo* gogo, int size)
{
  const char* tn;
  switch (size)
    {
    case 16:
      tn = "int16";
      break;
    case 32:
      tn = "int32";
      break;
    case 64:
      tn = "int64";
      break;
    case 128:
      // The code uses [2]int64, which must have the same alignment as
      // int64.
      tn = "int64";
      break;
    default:
      go_unreachable();
    }

  Type* t = Type::lookup_integer_type(tn);

  int64_t ret;
  if (!t->backend_type_align(gogo, &ret))
    go_unreachable();
  return ret;
}

// Return whether this type needs specially built type functions.
// This returns true for types that are comparable and either can not
// use an identity comparison, or are a non-standard size.

bool
Type::needs_specific_type_functions(Gogo* gogo)
{
  Named_type* nt = this->named_type();
  if (nt != NULL && nt->is_alias())
    return false;
  if (!this->is_comparable())
    return false;
  if (!this->compare_is_identity(gogo))
    return true;

  // We create a few predeclared types for type descriptors; they are
  // really just for the backend and don't need hash or equality
  // functions.
  if (nt != NULL && Linemap::is_predeclared_location(nt->location()))
    return false;

  int64_t size, align;
  if (!this->backend_type_size(gogo, &size)
      || !this->backend_type_align(gogo, &align))
    {
      go_assert(saw_errors());
      return false;
    }
  // This switch matches the one in Type::type_functions.
  switch (size)
    {
    case 0:
    case 1:
    case 2:
      return align < Type::memequal_align(gogo, 16);
    case 4:
      return align < Type::memequal_align(gogo, 32);
    case 8:
      return align < Type::memequal_align(gogo, 64);
    case 16:
      return align < Type::memequal_align(gogo, 128);
    default:
      return true;
    }
}

// Set *HASH_FN and *EQUAL_FN to the runtime functions which compute a
// hash code for this type and which compare whether two values of
// this type are equal.  If NAME is not NULL it is the name of this
// type.  HASH_FNTYPE and EQUAL_FNTYPE are the types of these
// functions, for convenience; they may be NULL.

void
Type::type_functions(Gogo* gogo, Named_type* name, Function_type* hash_fntype,
		     Function_type* equal_fntype, Named_object** hash_fn,
		     Named_object** equal_fn)
{
  // If the unaliased type is not a named type, then the type does not
  // have a name after all.
  if (name != NULL)
    name = name->unalias()->named_type();

  if (!this->is_comparable())
    {
      *hash_fn = NULL;
      *equal_fn = NULL;
      return;
    }

  if (hash_fntype == NULL || equal_fntype == NULL)
    {
      Location bloc = Linemap::predeclared_location();

      Type* uintptr_type = Type::lookup_integer_type("uintptr");
      Type* void_type = Type::make_void_type();
      Type* unsafe_pointer_type = Type::make_pointer_type(void_type);

      if (hash_fntype == NULL)
	{
	  Typed_identifier_list* params = new Typed_identifier_list();
	  params->push_back(Typed_identifier("key", unsafe_pointer_type,
					     bloc));
	  params->push_back(Typed_identifier("seed", uintptr_type, bloc));

	  Typed_identifier_list* results = new Typed_identifier_list();
	  results->push_back(Typed_identifier("", uintptr_type, bloc));

	  hash_fntype = Type::make_function_type(NULL, params, results, bloc);
	}
      if (equal_fntype == NULL)
	{
	  Typed_identifier_list* params = new Typed_identifier_list();
	  params->push_back(Typed_identifier("key1", unsafe_pointer_type,
					     bloc));
	  params->push_back(Typed_identifier("key2", unsafe_pointer_type,
					     bloc));

	  Typed_identifier_list* results = new Typed_identifier_list();
	  results->push_back(Typed_identifier("", Type::lookup_bool_type(),
					      bloc));

	  equal_fntype = Type::make_function_type(NULL, params, results, bloc);
	}
    }

  const char* hash_fnname;
  const char* equal_fnname;
  if (this->compare_is_identity(gogo))
    {
      int64_t size, align;
      if (!this->backend_type_size(gogo, &size)
	  || !this->backend_type_align(gogo, &align))
	{
	  go_assert(saw_errors());
	  return;
	}
      bool build_functions = false;
      // This switch matches the one in Type::needs_specific_type_functions.
      // The alignment tests are because of the memequal functions,
      // which assume that the values are aligned as required for an
      // integer of that size.
      switch (size)
	{
	case 0:
	  hash_fnname = "runtime.memhash0";
	  equal_fnname = "runtime.memequal0";
	  break;
	case 1:
	  hash_fnname = "runtime.memhash8";
	  equal_fnname = "runtime.memequal8";
	  break;
	case 2:
	  if (align < Type::memequal_align(gogo, 16))
	    build_functions = true;
	  else
	    {
	      hash_fnname = "runtime.memhash16";
	      equal_fnname = "runtime.memequal16";
	    }
	  break;
	case 4:
	  if (align < Type::memequal_align(gogo, 32))
	    build_functions = true;
	  else
	    {
	      hash_fnname = "runtime.memhash32";
	      equal_fnname = "runtime.memequal32";
	    }
	  break;
	case 8:
	  if (align < Type::memequal_align(gogo, 64))
	    build_functions = true;
	  else
	    {
	      hash_fnname = "runtime.memhash64";
	      equal_fnname = "runtime.memequal64";
	    }
	  break;
	case 16:
	  if (align < Type::memequal_align(gogo, 128))
	    build_functions = true;
	  else
	    {
	      hash_fnname = "runtime.memhash128";
	      equal_fnname = "runtime.memequal128";
	    }
	  break;
	default:
	  build_functions = true;
	  break;
	}
      if (build_functions)
	{
	  // We don't have a built-in function for a type of this size
	  // and alignment.  Build a function to use that calls the
	  // generic hash/equality functions for identity, passing the size.
	  this->specific_type_functions(gogo, name, size, hash_fntype,
					equal_fntype, hash_fn, equal_fn);
	  return;
	}
    }
  else
    {
      switch (this->base()->classification())
	{
	case Type::TYPE_ERROR:
	case Type::TYPE_VOID:
	case Type::TYPE_NIL:
	case Type::TYPE_FUNCTION:
	case Type::TYPE_MAP:
	  // For these types is_comparable should have returned false.
	  go_unreachable();

	case Type::TYPE_BOOLEAN:
	case Type::TYPE_INTEGER:
	case Type::TYPE_POINTER:
	case Type::TYPE_CHANNEL:
	  // For these types compare_is_identity should have returned true.
	  go_unreachable();

	case Type::TYPE_FLOAT:
	  switch (this->float_type()->bits())
	    {
	    case 32:
	      hash_fnname = "runtime.f32hash";
	      equal_fnname = "runtime.f32equal";
	      break;
	    case 64:
	      hash_fnname = "runtime.f64hash";
	      equal_fnname = "runtime.f64equal";
	      break;
	    default:
	      go_unreachable();
	    }
	  break;

	case Type::TYPE_COMPLEX:
	  switch (this->complex_type()->bits())
	    {
	    case 64:
	      hash_fnname = "runtime.c64hash";
	      equal_fnname = "runtime.c64equal";
	      break;
	    case 128:
	      hash_fnname = "runtime.c128hash";
	      equal_fnname = "runtime.c128equal";
	      break;
	    default:
	      go_unreachable();
	    }
	  break;

	case Type::TYPE_STRING:
	  hash_fnname = "runtime.strhash";
	  equal_fnname = "runtime.strequal";
	  break;

	case Type::TYPE_STRUCT:
	  {
	    // This is a struct which can not be compared using a
	    // simple identity function.  We need to build a function
	    // for comparison.
	    this->specific_type_functions(gogo, name, -1, hash_fntype,
					  equal_fntype, hash_fn, equal_fn);
	    return;
	  }

	case Type::TYPE_ARRAY:
	  if (this->is_slice_type())
	    {
	      // Type::is_compatible_for_comparison should have
	      // returned false.
	      go_unreachable();
	    }
	  else
	    {
	      // This is an array which can not be compared using a
	      // simple identity function.  We need to build a
	      // function for comparison.
	      this->specific_type_functions(gogo, name, -1, hash_fntype,
					    equal_fntype, hash_fn, equal_fn);
	      return;
	    }
	  break;

	case Type::TYPE_INTERFACE:
	  if (this->interface_type()->is_empty())
	    {
	      hash_fnname = "runtime.nilinterhash";
	      equal_fnname = "runtime.nilinterequal";
	    }
	  else
	    {
	      hash_fnname = "runtime.interhash";
	      equal_fnname = "runtime.interequal";
	    }
	  break;

	case Type::TYPE_NAMED:
	case Type::TYPE_FORWARD:
	  go_unreachable();

	default:
	  go_unreachable();
	}
    }


  Location bloc = Linemap::predeclared_location();
  *hash_fn = Named_object::make_function_declaration(hash_fnname, NULL,
						     hash_fntype, bloc);
  (*hash_fn)->func_declaration_value()->set_asm_name(hash_fnname);
  *equal_fn = Named_object::make_function_declaration(equal_fnname, NULL,
						      equal_fntype, bloc);
  (*equal_fn)->func_declaration_value()->set_asm_name(equal_fnname);
}

// A hash table mapping types to the specific hash functions.

Type::Type_functions Type::type_functions_table;

// Handle a type function which is specific to a type: if SIZE == -1,
// this is a struct or array that can not use an identity comparison.
// Otherwise, it is a type that uses an identity comparison but is not
// one of the standard supported sizes.

void
Type::specific_type_functions(Gogo* gogo, Named_type* name, int64_t size,
			      Function_type* hash_fntype,
			      Function_type* equal_fntype,
			      Named_object** hash_fn,
			      Named_object** equal_fn)
{
  Hash_equal_fn fnull(NULL, NULL);
  std::pair<Type*, Hash_equal_fn> val(name != NULL ? name : this, fnull);
  std::pair<Type_functions::iterator, bool> ins =
    Type::type_functions_table.insert(val);
  if (!ins.second)
    {
      // We already have functions for this type
      *hash_fn = ins.first->second.first;
      *equal_fn = ins.first->second.second;
      return;
    }

  std::string hash_name;
  std::string equal_name;
  gogo->specific_type_function_names(this, name, &hash_name, &equal_name);

  Location bloc = Linemap::predeclared_location();

  const Package* package = NULL;
  bool is_defined_elsewhere =
    this->type_descriptor_defined_elsewhere(name, &package);
  if (is_defined_elsewhere)
    {
      *hash_fn = Named_object::make_function_declaration(hash_name, package,
							 hash_fntype, bloc);
      *equal_fn = Named_object::make_function_declaration(equal_name, package,
							  equal_fntype, bloc);
    }
  else
    {
      *hash_fn = gogo->declare_package_function(hash_name, hash_fntype, bloc);
      *equal_fn = gogo->declare_package_function(equal_name, equal_fntype,
						 bloc);
    }

  ins.first->second.first = *hash_fn;
  ins.first->second.second = *equal_fn;

  if (!is_defined_elsewhere)
    {
      if (gogo->in_global_scope())
	this->write_specific_type_functions(gogo, name, size, hash_name,
					    hash_fntype, equal_name,
					    equal_fntype);
      else
	gogo->queue_specific_type_function(this, name, size, hash_name,
					   hash_fntype, equal_name,
					   equal_fntype);
    }
}

// Write the hash and equality functions for a type which needs to be
// written specially.

void
Type::write_specific_type_functions(Gogo* gogo, Named_type* name, int64_t size,
				    const std::string& hash_name,
				    Function_type* hash_fntype,
				    const std::string& equal_name,
				    Function_type* equal_fntype)
{
  Location bloc = Linemap::predeclared_location();

  if (gogo->specific_type_functions_are_written())
    {
      go_assert(saw_errors());
      return;
    }

  go_assert(this->is_comparable());

  Named_object* hash_fn = gogo->start_function(hash_name, hash_fntype, false,
					       bloc);
  hash_fn->func_value()->set_is_type_specific_function();
  gogo->start_block(bloc);

  if (size != -1)
    this->write_identity_hash(gogo, size);
  else if (name != NULL && name->real_type()->named_type() != NULL)
    this->write_named_hash(gogo, name, hash_fntype, equal_fntype);
  else if (this->struct_type() != NULL)
    this->struct_type()->write_hash_function(gogo, name, hash_fntype,
					     equal_fntype);
  else if (this->array_type() != NULL)
    this->array_type()->write_hash_function(gogo, name, hash_fntype,
					    equal_fntype);
  else
    go_unreachable();

  Block* b = gogo->finish_block(bloc);
  gogo->add_block(b, bloc);
  gogo->lower_block(hash_fn, b);
  gogo->finish_function(bloc);

  Named_object *equal_fn = gogo->start_function(equal_name, equal_fntype,
						false, bloc);
  equal_fn->func_value()->set_is_type_specific_function();
  gogo->start_block(bloc);

  if (size != -1)
    this->write_identity_equal(gogo, size);
  else if (name != NULL && name->real_type()->named_type() != NULL)
    this->write_named_equal(gogo, name);
  else if (this->struct_type() != NULL)
    this->struct_type()->write_equal_function(gogo, name);
  else if (this->array_type() != NULL)
    this->array_type()->write_equal_function(gogo, name);
  else
    go_unreachable();

  b = gogo->finish_block(bloc);
  gogo->add_block(b, bloc);
  gogo->lower_block(equal_fn, b);
  gogo->finish_function(bloc);

  // Build the function descriptors for the type descriptor to refer to.
  hash_fn->func_value()->descriptor(gogo, hash_fn);
  equal_fn->func_value()->descriptor(gogo, equal_fn);
}

// Write a hash function for a type that can use an identity hash but
// is not one of the standard supported sizes.  For example, this
// would be used for the type [3]byte.  This builds a return statement
// that returns a call to the memhash function, passing the key and
// seed from the function arguments (already constructed before this
// is called), and the constant size.

void
Type::write_identity_hash(Gogo* gogo, int64_t size)
{
  Location bloc = Linemap::predeclared_location();

  Type* unsafe_pointer_type = Type::make_pointer_type(Type::make_void_type());
  Type* uintptr_type = Type::lookup_integer_type("uintptr");

  Typed_identifier_list* params = new Typed_identifier_list();
  params->push_back(Typed_identifier("key", unsafe_pointer_type, bloc));
  params->push_back(Typed_identifier("seed", uintptr_type, bloc));
  params->push_back(Typed_identifier("size", uintptr_type, bloc));

  Typed_identifier_list* results = new Typed_identifier_list();
  results->push_back(Typed_identifier("", uintptr_type, bloc));

  Function_type* memhash_fntype = Type::make_function_type(NULL, params,
							   results, bloc);

  Named_object* memhash =
    Named_object::make_function_declaration("runtime.memhash", NULL,
					    memhash_fntype, bloc);
  memhash->func_declaration_value()->set_asm_name("runtime.memhash");

  Named_object* key_arg = gogo->lookup("key", NULL);
  go_assert(key_arg != NULL);
  Named_object* seed_arg = gogo->lookup("seed", NULL);
  go_assert(seed_arg != NULL);

  Expression* key_ref = Expression::make_var_reference(key_arg, bloc);
  Expression* seed_ref = Expression::make_var_reference(seed_arg, bloc);
  Expression* size_arg = Expression::make_integer_int64(size, uintptr_type,
							bloc);
  Expression_list* args = new Expression_list();
  args->push_back(key_ref);
  args->push_back(seed_ref);
  args->push_back(size_arg);
  Expression* func = Expression::make_func_reference(memhash, NULL, bloc);
  Expression* call = Expression::make_call(func, args, false, bloc);

  Expression_list* vals = new Expression_list();
  vals->push_back(call);
  Statement* s = Statement::make_return_statement(vals, bloc);
  gogo->add_statement(s);
}

// Write an equality function for a type that can use an identity
// equality comparison but is not one of the standard supported sizes.
// For example, this would be used for the type [3]byte.  This builds
// a return statement that returns a call to the memequal function,
// passing the two keys from the function arguments (already
// constructed before this is called), and the constant size.

void
Type::write_identity_equal(Gogo* gogo, int64_t size)
{
  Location bloc = Linemap::predeclared_location();

  Type* unsafe_pointer_type = Type::make_pointer_type(Type::make_void_type());
  Type* uintptr_type = Type::lookup_integer_type("uintptr");

  Typed_identifier_list* params = new Typed_identifier_list();
  params->push_back(Typed_identifier("key1", unsafe_pointer_type, bloc));
  params->push_back(Typed_identifier("key2", unsafe_pointer_type, bloc));
  params->push_back(Typed_identifier("size", uintptr_type, bloc));

  Typed_identifier_list* results = new Typed_identifier_list();
  results->push_back(Typed_identifier("", Type::lookup_bool_type(), bloc));

  Function_type* memequal_fntype = Type::make_function_type(NULL, params,
							    results, bloc);

  Named_object* memequal =
    Named_object::make_function_declaration("runtime.memequal", NULL,
					    memequal_fntype, bloc);
  memequal->func_declaration_value()->set_asm_name("runtime.memequal");

  Named_object* key1_arg = gogo->lookup("key1", NULL);
  go_assert(key1_arg != NULL);
  Named_object* key2_arg = gogo->lookup("key2", NULL);
  go_assert(key2_arg != NULL);

  Expression* key1_ref = Expression::make_var_reference(key1_arg, bloc);
  Expression* key2_ref = Expression::make_var_reference(key2_arg, bloc);
  Expression* size_arg = Expression::make_integer_int64(size, uintptr_type,
							bloc);
  Expression_list* args = new Expression_list();
  args->push_back(key1_ref);
  args->push_back(key2_ref);
  args->push_back(size_arg);
  Expression* func = Expression::make_func_reference(memequal, NULL, bloc);
  Expression* call = Expression::make_call(func, args, false, bloc);

  Expression_list* vals = new Expression_list();
  vals->push_back(call);
  Statement* s = Statement::make_return_statement(vals, bloc);
  gogo->add_statement(s);
}

// Write a hash function that simply calls the hash function for a
// named type.  This is used when one named type is defined as
// another.  This ensures that this case works when the other named
// type is defined in another package and relies on calling hash
// functions defined only in that package.

void
Type::write_named_hash(Gogo* gogo, Named_type* name,
		       Function_type* hash_fntype, Function_type* equal_fntype)
{
  Location bloc = Linemap::predeclared_location();

  Named_type* base_type = name->real_type()->named_type();
  while (base_type->is_alias())
    {
      base_type = base_type->real_type()->named_type();
      go_assert(base_type != NULL);
    }
  go_assert(base_type != NULL);

  // The pointer to the type we are going to hash.  This is an
  // unsafe.Pointer.
  Named_object* key_arg = gogo->lookup("key", NULL);
  go_assert(key_arg != NULL);

  // The seed argument to the hash function.
  Named_object* seed_arg = gogo->lookup("seed", NULL);
  go_assert(seed_arg != NULL);

  Named_object* hash_fn;
  Named_object* equal_fn;
  name->real_type()->type_functions(gogo, base_type, hash_fntype, equal_fntype,
				    &hash_fn, &equal_fn);

  // Call the hash function for the base type.
  Expression* key_ref = Expression::make_var_reference(key_arg, bloc);
  Expression* seed_ref = Expression::make_var_reference(seed_arg, bloc);
  Expression_list* args = new Expression_list();
  args->push_back(key_ref);
  args->push_back(seed_ref);
  Expression* func = Expression::make_func_reference(hash_fn, NULL, bloc);
  Expression* call = Expression::make_call(func, args, false, bloc);

  // Return the hash of the base type.
  Expression_list* vals = new Expression_list();
  vals->push_back(call);
  Statement* s = Statement::make_return_statement(vals, bloc);
  gogo->add_statement(s);
}

// Write an equality function that simply calls the equality function
// for a named type.  This is used when one named type is defined as
// another.  This ensures that this case works when the other named
// type is defined in another package and relies on calling equality
// functions defined only in that package.

void
Type::write_named_equal(Gogo* gogo, Named_type* name)
{
  Location bloc = Linemap::predeclared_location();

  // The pointers to the types we are going to compare.  These have
  // type unsafe.Pointer.
  Named_object* key1_arg = gogo->lookup("key1", NULL);
  Named_object* key2_arg = gogo->lookup("key2", NULL);
  go_assert(key1_arg != NULL && key2_arg != NULL);

  Named_type* base_type = name->real_type()->named_type();
  go_assert(base_type != NULL);

  // Build temporaries with the base type.
  Type* pt = Type::make_pointer_type(base_type);

  Expression* ref = Expression::make_var_reference(key1_arg, bloc);
  ref = Expression::make_cast(pt, ref, bloc);
  Temporary_statement* p1 = Statement::make_temporary(pt, ref, bloc);
  gogo->add_statement(p1);

  ref = Expression::make_var_reference(key2_arg, bloc);
  ref = Expression::make_cast(pt, ref, bloc);
  Temporary_statement* p2 = Statement::make_temporary(pt, ref, bloc);
  gogo->add_statement(p2);

  // Compare the values for equality.
  Expression* t1 = Expression::make_temporary_reference(p1, bloc);
  t1 = Expression::make_dereference(t1, Expression::NIL_CHECK_NOT_NEEDED, bloc);

  Expression* t2 = Expression::make_temporary_reference(p2, bloc);
  t2 = Expression::make_dereference(t2, Expression::NIL_CHECK_NOT_NEEDED, bloc);

  Expression* cond = Expression::make_binary(OPERATOR_EQEQ, t1, t2, bloc);

  // Return the equality comparison.
  Expression_list* vals = new Expression_list();
  vals->push_back(cond);
  Statement* s = Statement::make_return_statement(vals, bloc);
  gogo->add_statement(s);
}

// Return a composite literal for the type descriptor for a plain type
// of kind RUNTIME_TYPE_KIND named NAME.

Expression*
Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind,
				  Named_type* name, const Methods* methods,
				  bool only_value_methods)
{
  Location bloc = Linemap::predeclared_location();

  Type* td_type = Type::make_type_descriptor_type();
  const Struct_field_list* fields = td_type->struct_type()->fields();

  Expression_list* vals = new Expression_list();
  vals->reserve(12);

  if (!this->has_pointer())
    runtime_type_kind |= RUNTIME_TYPE_KIND_NO_POINTERS;
  if (this->points_to() != NULL)
    runtime_type_kind |= RUNTIME_TYPE_KIND_DIRECT_IFACE;
  int64_t ptrsize;
  int64_t ptrdata;
  if (this->needs_gcprog(gogo, &ptrsize, &ptrdata))
    runtime_type_kind |= RUNTIME_TYPE_KIND_GC_PROG;

  Struct_field_list::const_iterator p = fields->begin();
  go_assert(p->is_field_name("size"));
  Expression::Type_info type_info = Expression::TYPE_INFO_SIZE;
  vals->push_back(Expression::make_type_info(this, type_info));

  ++p;
  go_assert(p->is_field_name("ptrdata"));
  type_info = Expression::TYPE_INFO_DESCRIPTOR_PTRDATA;
  vals->push_back(Expression::make_type_info(this, type_info));

  ++p;
  go_assert(p->is_field_name("hash"));
  unsigned int h;
  if (name != NULL)
    h = name->hash_for_method(gogo, Type::COMPARE_TAGS);
  else
    h = this->hash_for_method(gogo, Type::COMPARE_TAGS);
  vals->push_back(Expression::make_integer_ul(h, p->type(), bloc));

  ++p;
  go_assert(p->is_field_name("kind"));
  vals->push_back(Expression::make_integer_ul(runtime_type_kind, p->type(),
					      bloc));

  ++p;
  go_assert(p->is_field_name("align"));
  type_info = Expression::TYPE_INFO_ALIGNMENT;
  vals->push_back(Expression::make_type_info(this, type_info));

  ++p;
  go_assert(p->is_field_name("fieldAlign"));
  type_info = Expression::TYPE_INFO_FIELD_ALIGNMENT;
  vals->push_back(Expression::make_type_info(this, type_info));

  ++p;
  go_assert(p->is_field_name("hashfn"));
  Function_type* hash_fntype = p->type()->function_type();

  ++p;
  go_assert(p->is_field_name("equalfn"));
  Function_type* equal_fntype = p->type()->function_type();

  Named_object* hash_fn;
  Named_object* equal_fn;
  this->type_functions(gogo, name, hash_fntype, equal_fntype, &hash_fn,
		       &equal_fn);
  if (hash_fn == NULL)
    vals->push_back(Expression::make_cast(hash_fntype,
					  Expression::make_nil(bloc),
					  bloc));
  else
    vals->push_back(Expression::make_func_reference(hash_fn, NULL, bloc));
  if (equal_fn == NULL)
    vals->push_back(Expression::make_cast(equal_fntype,
					  Expression::make_nil(bloc),
					  bloc));
  else
    vals->push_back(Expression::make_func_reference(equal_fn, NULL, bloc));

  ++p;
  go_assert(p->is_field_name("gcdata"));
  vals->push_back(Expression::make_gc_symbol(this));

  ++p;
  go_assert(p->is_field_name("string"));
  Expression* s = Expression::make_string((name != NULL
					   ? name->reflection(gogo)
					   : this->reflection(gogo)),
					  bloc);
  vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));

  ++p;
  go_assert(p->is_field_name("uncommonType"));
  if (name == NULL && methods == NULL)
    vals->push_back(Expression::make_nil(bloc));
  else
    {
      if (methods == NULL)
	methods = name->methods();
      vals->push_back(this->uncommon_type_constructor(gogo,
						      p->type()->deref(),
						      name, methods,
						      only_value_methods));
    }

  ++p;
  go_assert(p->is_field_name("ptrToThis"));
  if (name == NULL && methods == NULL)
    vals->push_back(Expression::make_nil(bloc));
  else
    {
      Type* pt;
      if (name != NULL)
	pt = Type::make_pointer_type(name);
      else
	pt = Type::make_pointer_type(this);
      vals->push_back(Expression::make_type_descriptor(pt, bloc));
    }

  ++p;
  go_assert(p == fields->end());

  return Expression::make_struct_composite_literal(td_type, vals, bloc);
}

// The maximum length of a GC ptrmask bitmap.  This corresponds to the
// length used by the gc toolchain, and also appears in
// libgo/go/reflect/type.go.

static const int64_t max_ptrmask_bytes = 2048;

// Return a pointer to the Garbage Collection information for this type.

Bexpression*
Type::gc_symbol_pointer(Gogo* gogo)
{
  Type* t = this->unalias();

  if (!t->has_pointer())
    return gogo->backend()->nil_pointer_expression();

  if (t->gc_symbol_var_ == NULL)
    {
      t->make_gc_symbol_var(gogo);
      go_assert(t->gc_symbol_var_ != NULL);
    }
  Location bloc = Linemap::predeclared_location();
  Bexpression* var_expr =
      gogo->backend()->var_expression(t->gc_symbol_var_, bloc);
  Bexpression* addr_expr =
      gogo->backend()->address_expression(var_expr, bloc);

  Type* uint8_type = Type::lookup_integer_type("uint8");
  Type* pointer_uint8_type = Type::make_pointer_type(uint8_type);
  Btype* ubtype = pointer_uint8_type->get_backend(gogo);
  return gogo->backend()->convert_expression(ubtype, addr_expr, bloc);
}

// A mapping from unnamed types to GC symbol variables.

Type::GC_symbol_vars Type::gc_symbol_vars;

// Build the GC symbol for this type.

void
Type::make_gc_symbol_var(Gogo* gogo)
{
  go_assert(this->gc_symbol_var_ == NULL);

  Named_type* nt = this->named_type();

  // We can have multiple instances of unnamed types and similar to type
  // descriptors, we only want to the emit the GC data once, so we use a
  // hash table.
  Bvariable** phash = NULL;
  if (nt == NULL)
    {
      Bvariable* bvnull = NULL;
      std::pair<GC_symbol_vars::iterator, bool> ins =
	Type::gc_symbol_vars.insert(std::make_pair(this, bvnull));
      if (!ins.second)
	{
	  // We've already built a gc symbol for this type.
	  this->gc_symbol_var_ = ins.first->second;
	  return;
	}
      phash = &ins.first->second;
    }

  int64_t ptrsize;
  int64_t ptrdata;
  if (!this->needs_gcprog(gogo, &ptrsize, &ptrdata))
    {
      this->gc_symbol_var_ = this->gc_ptrmask_var(gogo, ptrsize, ptrdata);
      if (phash != NULL)
	*phash = this->gc_symbol_var_;
      return;
    }

  std::string sym_name = gogo->gc_symbol_name(this);

  // Build the contents of the gc symbol.
  Expression* sym_init = this->gcprog_constructor(gogo, ptrsize, ptrdata);
  Btype* sym_btype = sym_init->type()->get_backend(gogo);

  // If the type descriptor for this type is defined somewhere else, so is the
  // GC symbol.
  const Package* dummy;
  if (this->type_descriptor_defined_elsewhere(nt, &dummy))
    {
      std::string asm_name(go_selectively_encode_id(sym_name));
      this->gc_symbol_var_ =
          gogo->backend()->implicit_variable_reference(sym_name, asm_name,
                                                       sym_btype);
      if (phash != NULL)
	*phash = this->gc_symbol_var_;
      return;
    }

  // See if this gc symbol can appear in multiple packages.
  bool is_common = false;
  if (nt != NULL)
    {
      // We create the symbol for a builtin type whenever we need
      // it.
      is_common = nt->is_builtin();
    }
  else
    {
      // This is an unnamed type.  The descriptor could be defined in
      // any package where it is needed, and the linker will pick one
      // descriptor to keep.
      is_common = true;
    }

  // Since we are building the GC symbol in this package, we must create the
  // variable before converting the initializer to its backend representation
  // because the initializer may refer to the GC symbol for this type.
  std::string asm_name(go_selectively_encode_id(sym_name));
  this->gc_symbol_var_ =
      gogo->backend()->implicit_variable(sym_name, asm_name,
					 sym_btype, false, true, is_common, 0);
  if (phash != NULL)
    *phash = this->gc_symbol_var_;

  Translate_context context(gogo, NULL, NULL, NULL);
  context.set_is_const();
  Bexpression* sym_binit = sym_init->get_backend(&context);
  gogo->backend()->implicit_variable_set_init(this->gc_symbol_var_, sym_name,
					      sym_btype, false, true, is_common,
					      sym_binit);
}

// Return whether this type needs a GC program, and set *PTRDATA to
// the size of the pointer data in bytes and *PTRSIZE to the size of a
// pointer.

bool
Type::needs_gcprog(Gogo* gogo, int64_t* ptrsize, int64_t* ptrdata)
{
  Type* voidptr = Type::make_pointer_type(Type::make_void_type());
  if (!voidptr->backend_type_size(gogo, ptrsize))
    go_unreachable();

  if (!this->backend_type_ptrdata(gogo, ptrdata))
    {
      go_assert(saw_errors());
      return false;
    }

  return *ptrdata / *ptrsize > max_ptrmask_bytes;
}

// A simple class used to build a GC ptrmask for a type.

class Ptrmask
{
 public:
  Ptrmask(size_t count)
    : bits_((count + 7) / 8, 0)
  {}

  void
  set_from(Gogo*, Type*, int64_t ptrsize, int64_t offset);

  std::string
  symname() const;

  Expression*
  constructor(Gogo* gogo) const;

 private:
  void
  set(size_t index)
  { this->bits_.at(index / 8) |= 1 << (index % 8); }

  // The actual bits.
  std::vector<unsigned char> bits_;
};

// Set bits in ptrmask starting from OFFSET based on TYPE.  OFFSET
// counts in bytes.  PTRSIZE is the size of a pointer on the target
// system.

void
Ptrmask::set_from(Gogo* gogo, Type* type, int64_t ptrsize, int64_t offset)
{
  switch (type->base()->classification())
    {
    default:
    case Type::TYPE_NIL:
    case Type::TYPE_CALL_MULTIPLE_RESULT:
    case Type::TYPE_NAMED:
    case Type::TYPE_FORWARD:
      go_unreachable();

    case Type::TYPE_ERROR:
    case Type::TYPE_VOID:
    case Type::TYPE_BOOLEAN:
    case Type::TYPE_INTEGER:
    case Type::TYPE_FLOAT:
    case Type::TYPE_COMPLEX:
    case Type::TYPE_SINK:
      break;

    case Type::TYPE_FUNCTION:
    case Type::TYPE_POINTER:
    case Type::TYPE_MAP:
    case Type::TYPE_CHANNEL:
      // These types are all a single pointer.
      go_assert((offset % ptrsize) == 0);
      this->set(offset / ptrsize);
      break;

    case Type::TYPE_STRING:
      // A string starts with a single pointer.
      go_assert((offset % ptrsize) == 0);
      this->set(offset / ptrsize);
      break;

    case Type::TYPE_INTERFACE:
      // An interface is two pointers.
      go_assert((offset % ptrsize) == 0);
      this->set(offset / ptrsize);
      this->set((offset / ptrsize) + 1);
      break;

    case Type::TYPE_STRUCT:
      {
	if (!type->has_pointer())
	  return;

	const Struct_field_list* fields = type->struct_type()->fields();
	int64_t soffset = 0;
	for (Struct_field_list::const_iterator pf = fields->begin();
	     pf != fields->end();
	     ++pf)
	  {
	    int64_t field_align;
	    if (!pf->type()->backend_type_field_align(gogo, &field_align))
	      {
		go_assert(saw_errors());
		return;
	      }
	    soffset = (soffset + (field_align - 1)) &~ (field_align - 1);

	    this->set_from(gogo, pf->type(), ptrsize, offset + soffset);

	    int64_t field_size;
	    if (!pf->type()->backend_type_size(gogo, &field_size))
	      {
		go_assert(saw_errors());
		return;
	      }
	    soffset += field_size;
	  }
      }
      break;

    case Type::TYPE_ARRAY:
      if (type->is_slice_type())
	{
	  // A slice starts with a single pointer.
	  go_assert((offset % ptrsize) == 0);
	  this->set(offset / ptrsize);
	  break;
	}
      else
	{
	  if (!type->has_pointer())
	    return;

	  int64_t len;
	  if (!type->array_type()->int_length(&len))
	    {
	      go_assert(saw_errors());
	      return;
	    }

	  Type* element_type = type->array_type()->element_type();
	  int64_t ele_size;
	  if (!element_type->backend_type_size(gogo, &ele_size))
	    {
	      go_assert(saw_errors());
	      return;
	    }

	  int64_t eoffset = 0;
	  for (int64_t i = 0; i < len; i++, eoffset += ele_size)
	    this->set_from(gogo, element_type, ptrsize, offset + eoffset);
	  break;
	}
    }
}

// Return a symbol name for this ptrmask.  This is used to coalesce
// identical ptrmasks, which are common.  The symbol name must use
// only characters that are valid in symbols.  It's nice if it's
// short.  We convert it to a string that uses only 32 characters,
// avoiding digits and u and U.

std::string
Ptrmask::symname() const
{
  const char chars[33] = "abcdefghijklmnopqrstvwxyzABCDEFG";
  go_assert(chars[32] == '\0');
  std::string ret;
  unsigned int b = 0;
  int remaining = 0;
  for (std::vector<unsigned char>::const_iterator p = this->bits_.begin();
       p != this->bits_.end();
       ++p)
    {
      b |= *p << remaining;
      remaining += 8;
      while (remaining >= 5)
	{
	  ret += chars[b & 0x1f];
	  b >>= 5;
	  remaining -= 5;
	}
    }
  while (remaining > 0)
    {
      ret += chars[b & 0x1f];
      b >>= 5;
      remaining -= 5;
    }
  return ret;
}

// Return a constructor for this ptrmask.  This will be used to
// initialize the runtime ptrmask value.

Expression*
Ptrmask::constructor(Gogo* gogo) const
{
  Location bloc = Linemap::predeclared_location();
  Type* byte_type = gogo->lookup_global("byte")->type_value();
  Expression* len = Expression::make_integer_ul(this->bits_.size(), NULL,
						bloc);
  Array_type* at = Type::make_array_type(byte_type, len);
  Expression_list* vals = new Expression_list();
  vals->reserve(this->bits_.size());
  for (std::vector<unsigned char>::const_iterator p = this->bits_.begin();
       p != this->bits_.end();
       ++p)
    vals->push_back(Expression::make_integer_ul(*p, byte_type, bloc));
  return Expression::make_array_composite_literal(at, vals, bloc);
}

// The hash table mapping a ptrmask symbol name to the ptrmask variable.
Type::GC_gcbits_vars Type::gc_gcbits_vars;

// Return a ptrmask variable for a type.  For a type descriptor this
// is only used for variables that are small enough to not need a
// gcprog, but for a global variable this is used for a variable of
// any size.  PTRDATA is the number of bytes of the type that contain
// pointer data.  PTRSIZE is the size of a pointer on the target
// system.

Bvariable*
Type::gc_ptrmask_var(Gogo* gogo, int64_t ptrsize, int64_t ptrdata)
{
  Ptrmask ptrmask(ptrdata / ptrsize);
  if (ptrdata >= ptrsize)
    ptrmask.set_from(gogo, this, ptrsize, 0);
  else
    {
      // This can happen in error cases.  Just build an empty gcbits.
      go_assert(saw_errors());
    }

  std::string sym_name = gogo->ptrmask_symbol_name(ptrmask.symname());
  Bvariable* bvnull = NULL;
  std::pair<GC_gcbits_vars::iterator, bool> ins =
    Type::gc_gcbits_vars.insert(std::make_pair(sym_name, bvnull));
  if (!ins.second)
    {
      // We've already built a GC symbol for this set of gcbits.
      return ins.first->second;
    }

  Expression* val = ptrmask.constructor(gogo);
  Translate_context context(gogo, NULL, NULL, NULL);
  context.set_is_const();
  Bexpression* bval = val->get_backend(&context);

  std::string asm_name(go_selectively_encode_id(sym_name));
  Btype *btype = val->type()->get_backend(gogo);
  Bvariable* ret = gogo->backend()->implicit_variable(sym_name, asm_name,
						      btype, false, true,
						      true, 0);
  gogo->backend()->implicit_variable_set_init(ret, sym_name, btype, false,
					      true, true, bval);
  ins.first->second = ret;
  return ret;
}

// A GCProg is used to build a program for the garbage collector.
// This is used for types with a lot of pointer data, to reduce the
// size of the data in the compiled program.  The program is expanded
// at runtime.  For the format, see runGCProg in libgo/go/runtime/mbitmap.go.

class GCProg
{
 public:
  GCProg()
    : bytes_(), index_(0), nb_(0)
  {}

  // The number of bits described so far.
  int64_t
  bit_index() const
  { return this->index_; }

  void
  set_from(Gogo*, Type*, int64_t ptrsize, int64_t offset);

  void
  end();

  Expression*
  constructor(Gogo* gogo) const;

 private:
  void
  ptr(int64_t);

  bool
  should_repeat(int64_t, int64_t);

  void
  repeat(int64_t, int64_t);

  void
  zero_until(int64_t);

  void
  lit(unsigned char);

  void
  varint(int64_t);

  void
  flushlit();

  // Add a byte to the program.
  void
  byte(unsigned char x)
  { this->bytes_.push_back(x); }

  // The maximum number of bytes of literal bits.
  static const int max_literal = 127;

  // The program.
  std::vector<unsigned char> bytes_;
  // The index of the last bit described.
  int64_t index_;
  // The current set of literal bits.
  unsigned char b_[max_literal];
  // The current number of literal bits.
  int nb_;
};

// Set data in gcprog starting from OFFSET based on TYPE.  OFFSET
// counts in bytes.  PTRSIZE is the size of a pointer on the target
// system.

void
GCProg::set_from(Gogo* gogo, Type* type, int64_t ptrsize, int64_t offset)
{
  switch (type->base()->classification())
    {
    default:
    case Type::TYPE_NIL:
    case Type::TYPE_CALL_MULTIPLE_RESULT:
    case Type::TYPE_NAMED:
    case Type::TYPE_FORWARD:
      go_unreachable();

    case Type::TYPE_ERROR:
    case Type::TYPE_VOID:
    case Type::TYPE_BOOLEAN:
    case Type::TYPE_INTEGER:
    case Type::TYPE_FLOAT:
    case Type::TYPE_COMPLEX:
    case Type::TYPE_SINK:
      break;

    case Type::TYPE_FUNCTION:
    case Type::TYPE_POINTER:
    case Type::TYPE_MAP:
    case Type::TYPE_CHANNEL:
      // These types are all a single pointer.
      go_assert((offset % ptrsize) == 0);
      this->ptr(offset / ptrsize);
      break;

    case Type::TYPE_STRING:
      // A string starts with a single pointer.
      go_assert((offset % ptrsize) == 0);
      this->ptr(offset / ptrsize);
      break;

    case Type::TYPE_INTERFACE:
      // An interface is two pointers.
      go_assert((offset % ptrsize) == 0);
      this->ptr(offset / ptrsize);
      this->ptr((offset / ptrsize) + 1);
      break;

    case Type::TYPE_STRUCT:
      {
	if (!type->has_pointer())
	  return;

	const Struct_field_list* fields = type->struct_type()->fields();
	int64_t soffset = 0;
	for (Struct_field_list::const_iterator pf = fields->begin();
	     pf != fields->end();
	     ++pf)
	  {
	    int64_t field_align;
	    if (!pf->type()->backend_type_field_align(gogo, &field_align))
	      {
		go_assert(saw_errors());
		return;
	      }
	    soffset = (soffset + (field_align - 1)) &~ (field_align - 1);

	    this->set_from(gogo, pf->type(), ptrsize, offset + soffset);

	    int64_t field_size;
	    if (!pf->type()->backend_type_size(gogo, &field_size))
	      {
		go_assert(saw_errors());
		return;
	      }
	    soffset += field_size;
	  }
      }
      break;

    case Type::TYPE_ARRAY:
      if (type->is_slice_type())
	{
	  // A slice starts with a single pointer.
	  go_assert((offset % ptrsize) == 0);
	  this->ptr(offset / ptrsize);
	  break;
	}
      else
	{
	  if (!type->has_pointer())
	    return;

	  int64_t len;
	  if (!type->array_type()->int_length(&len))
	    {
	      go_assert(saw_errors());
	      return;
	    }

	  Type* element_type = type->array_type()->element_type();

	  // Flatten array of array to a big array by multiplying counts.
	  while (element_type->array_type() != NULL
		 && !element_type->is_slice_type())
	    {
	      int64_t ele_len;
	      if (!element_type->array_type()->int_length(&ele_len))
		{
		  go_assert(saw_errors());
		  return;
		}

	      len *= ele_len;
	      element_type = element_type->array_type()->element_type();
	    }

	  int64_t ele_size;
	  if (!element_type->backend_type_size(gogo, &ele_size))
	    {
	      go_assert(saw_errors());
	      return;
	    }

	  go_assert(len > 0 && ele_size > 0);

	  if (!this->should_repeat(ele_size / ptrsize, len))
	    {
	      // Cheaper to just emit the bits.
	      int64_t eoffset = 0;
	      for (int64_t i = 0; i < len; i++, eoffset += ele_size)
		this->set_from(gogo, element_type, ptrsize, offset + eoffset);
	    }
	  else
	    {
	      go_assert((offset % ptrsize) == 0);
	      go_assert((ele_size % ptrsize) == 0);
	      this->set_from(gogo, element_type, ptrsize, offset);
	      this->zero_until((offset + ele_size) / ptrsize);
	      this->repeat(ele_size / ptrsize, len - 1);
	    }

	  break;
	}
    }
}

// Emit a 1 into the bit stream of a GC program at the given bit index.

void
GCProg::ptr(int64_t index)
{
  go_assert(index >= this->index_);
  this->zero_until(index);
  this->lit(1);
}

// Return whether it is worthwhile to use a repeat to describe c
// elements of n bits each, compared to just emitting c copies of the
// n-bit description.

bool
GCProg::should_repeat(int64_t n, int64_t c)
{
  // Repeat if there is more than 1 item and if the total data doesn't
  // fit into four bytes.
  return c > 1 && c * n > 4 * 8;
}

// Emit an instruction to repeat the description of the last n words c
// times (including the initial description, so c + 1 times in total).

void
GCProg::repeat(int64_t n, int64_t c)
{
  if (n == 0 || c == 0)
    return;
  this->flushlit();
  if (n < 128)
    this->byte(0x80 | static_cast<unsigned char>(n & 0x7f));
  else
    {
      this->byte(0x80);
      this->varint(n);
    }
  this->varint(c);
  this->index_ += n * c;
}

// Add zeros to the bit stream up to the given index.

void
GCProg::zero_until(int64_t index)
{
  go_assert(index >= this->index_);
  int64_t skip = index - this->index_;
  if (skip == 0)
    return;
  if (skip < 4 * 8)
    {
      for (int64_t i = 0; i < skip; ++i)
	this->lit(0);
      return;
    }
  this->lit(0);
  this->flushlit();
  this->repeat(1, skip - 1);
}

// Add a single literal bit to the program.

void
GCProg::lit(unsigned char x)
{
  if (this->nb_ == GCProg::max_literal)
    this->flushlit();
  this->b_[this->nb_] = x;
  ++this->nb_;
  ++this->index_;
}

// Emit the varint encoding of x.

void
GCProg::varint(int64_t x)
{
  go_assert(x >= 0);
  while (x >= 0x80)
    {
      this->byte(0x80 | static_cast<unsigned char>(x & 0x7f));
      x >>= 7;
    }
  this->byte(static_cast<unsigned char>(x & 0x7f));
}

// Flush any pending literal bits.

void
GCProg::flushlit()
{
  if (this->nb_ == 0)
    return;
  this->byte(static_cast<unsigned char>(this->nb_));
  unsigned char bits = 0;
  for (int i = 0; i < this->nb_; ++i)
    {
      bits |= this->b_[i] << (i % 8);
      if ((i + 1) % 8 == 0)
	{
	  this->byte(bits);
	  bits = 0;
	}
    }
  if (this->nb_ % 8 != 0)
    this->byte(bits);
  this->nb_ = 0;
}

// Mark the end of a GC program.

void
GCProg::end()
{
  this->flushlit();
  this->byte(0);
}

// Return an Expression for the bytes in a GC program.

Expression*
GCProg::constructor(Gogo* gogo) const
{
  Location bloc = Linemap::predeclared_location();

  // The first four bytes are the length of the program in target byte
  // order.  Build a struct whose first type is uint32 to make this
  // work.

  Type* uint32_type = Type::lookup_integer_type("uint32");

  Type* byte_type = gogo->lookup_global("byte")->type_value();
  Expression* len = Expression::make_integer_ul(this->bytes_.size(), NULL,
						bloc);
  Array_type* at = Type::make_array_type(byte_type, len);

  Struct_type* st = Type::make_builtin_struct_type(2, "len", uint32_type,
						   "bytes", at);

  Expression_list* vals = new Expression_list();
  vals->reserve(this->bytes_.size());
  for (std::vector<unsigned char>::const_iterator p = this->bytes_.begin();
       p != this->bytes_.end();
       ++p)
    vals->push_back(Expression::make_integer_ul(*p, byte_type, bloc));
  Expression* bytes = Expression::make_array_composite_literal(at, vals, bloc);

  vals = new Expression_list();
  vals->push_back(Expression::make_integer_ul(this->bytes_.size(), uint32_type,
					      bloc));
  vals->push_back(bytes);

  return Expression::make_struct_composite_literal(st, vals, bloc);
}

// Return a composite literal for the garbage collection program for
// this type.  This is only used for types that are too large to use a
// ptrmask.

Expression*
Type::gcprog_constructor(Gogo* gogo, int64_t ptrsize, int64_t ptrdata)
{
  Location bloc = Linemap::predeclared_location();

  GCProg prog;
  prog.set_from(gogo, this, ptrsize, 0);
  int64_t offset = prog.bit_index() * ptrsize;
  prog.end();

  int64_t type_size;
  if (!this->backend_type_size(gogo, &type_size))
    {
      go_assert(saw_errors());
      return Expression::make_error(bloc);
    }

  go_assert(offset >= ptrdata && offset <= type_size);

  return prog.constructor(gogo);
}

// Return a composite literal for the uncommon type information for
// this type.  UNCOMMON_STRUCT_TYPE is the type of the uncommon type
// struct.  If name is not NULL, it is the name of the type.  If
// METHODS is not NULL, it is the list of methods.  ONLY_VALUE_METHODS
// is true if only value methods should be included.  At least one of
// NAME and METHODS must not be NULL.

Expression*
Type::uncommon_type_constructor(Gogo* gogo, Type* uncommon_type,
				Named_type* name, const Methods* methods,
				bool only_value_methods) const
{
  Location bloc = Linemap::predeclared_location();

  const Struct_field_list* fields = uncommon_type->struct_type()->fields();

  Expression_list* vals = new Expression_list();
  vals->reserve(3);

  Struct_field_list::const_iterator p = fields->begin();
  go_assert(p->is_field_name("name"));

  ++p;
  go_assert(p->is_field_name("pkgPath"));

  if (name == NULL)
    {
      vals->push_back(Expression::make_nil(bloc));
      vals->push_back(Expression::make_nil(bloc));
    }
  else
    {
      Named_object* no = name->named_object();
      std::string n = Gogo::unpack_hidden_name(no->name());
      Expression* s = Expression::make_string(n, bloc);
      vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));

      if (name->is_builtin())
	vals->push_back(Expression::make_nil(bloc));
      else
	{
	  const Package* package = no->package();
	  const std::string& pkgpath(package == NULL
				     ? gogo->pkgpath()
				     : package->pkgpath());
	  s = Expression::make_string(pkgpath, bloc);
	  vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
	}
    }

  ++p;
  go_assert(p->is_field_name("methods"));
  vals->push_back(this->methods_constructor(gogo, p->type(), methods,
					    only_value_methods));

  ++p;
  go_assert(p == fields->end());

  Expression* r = Expression::make_struct_composite_literal(uncommon_type,
							    vals, bloc);
  return Expression::make_unary(OPERATOR_AND, r, bloc);
}

// Sort methods by name.

class Sort_methods
{
 public:
  bool
  operator()(const std::pair<std::string, const Method*>& m1,
	     const std::pair<std::string, const Method*>& m2) const
  {
    return (Gogo::unpack_hidden_name(m1.first)
	    < Gogo::unpack_hidden_name(m2.first));
  }
};

// Return a composite literal for the type method table for this type.
// METHODS_TYPE is the type of the table, and is a slice type.
// METHODS is the list of methods.  If ONLY_VALUE_METHODS is true,
// then only value methods are used.

Expression*
Type::methods_constructor(Gogo* gogo, Type* methods_type,
			  const Methods* methods,
			  bool only_value_methods) const
{
  Location bloc = Linemap::predeclared_location();

  std::vector<std::pair<std::string, const Method*> > smethods;
  if (methods != NULL)
    {
      smethods.reserve(methods->count());
      for (Methods::const_iterator p = methods->begin();
	   p != methods->end();
	   ++p)
	{
	  if (p->second->is_ambiguous())
	    continue;
	  if (only_value_methods && !p->second->is_value_method())
	    continue;

	  // This is where we implement the magic //go:nointerface
	  // comment.  If we saw that comment, we don't add this
	  // method to the type descriptor.
	  if (p->second->nointerface())
	    continue;

	  smethods.push_back(std::make_pair(p->first, p->second));
	}
    }

  if (smethods.empty())
    return Expression::make_slice_composite_literal(methods_type, NULL, bloc);

  std::sort(smethods.begin(), smethods.end(), Sort_methods());

  Type* method_type = methods_type->array_type()->element_type();

  Expression_list* vals = new Expression_list();
  vals->reserve(smethods.size());
  for (std::vector<std::pair<std::string, const Method*> >::const_iterator p
	 = smethods.begin();
       p != smethods.end();
       ++p)
    vals->push_back(this->method_constructor(gogo, method_type, p->first,
					     p->second, only_value_methods));

  return Expression::make_slice_composite_literal(methods_type, vals, bloc);
}

// Return a composite literal for a single method.  METHOD_TYPE is the
// type of the entry.  METHOD_NAME is the name of the method and M is
// the method information.

Expression*
Type::method_constructor(Gogo*, Type* method_type,
			 const std::string& method_name,
			 const Method* m,
			 bool only_value_methods) const
{
  Location bloc = Linemap::predeclared_location();

  const Struct_field_list* fields = method_type->struct_type()->fields();

  Expression_list* vals = new Expression_list();
  vals->reserve(5);

  Struct_field_list::const_iterator p = fields->begin();
  go_assert(p->is_field_name("name"));
  const std::string n = Gogo::unpack_hidden_name(method_name);
  Expression* s = Expression::make_string(n, bloc);
  vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));

  ++p;
  go_assert(p->is_field_name("pkgPath"));
  if (!Gogo::is_hidden_name(method_name))
    vals->push_back(Expression::make_nil(bloc));
  else
    {
      s = Expression::make_string(Gogo::hidden_name_pkgpath(method_name),
				  bloc);
      vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
    }

  Named_object* no = (m->needs_stub_method()
		      ? m->stub_object()
		      : m->named_object());

  Function_type* mtype;
  if (no->is_function())
    mtype = no->func_value()->type();
  else
    mtype = no->func_declaration_value()->type();
  go_assert(mtype->is_method());
  Type* nonmethod_type = mtype->copy_without_receiver();

  ++p;
  go_assert(p->is_field_name("mtyp"));
  vals->push_back(Expression::make_type_descriptor(nonmethod_type, bloc));

  ++p;
  go_assert(p->is_field_name("typ"));
  bool want_pointer_receiver = !only_value_methods && m->is_value_method();
  nonmethod_type = mtype->copy_with_receiver_as_param(want_pointer_receiver);
  vals->push_back(Expression::make_type_descriptor(nonmethod_type, bloc));

  ++p;
  go_assert(p->is_field_name("tfn"));
  vals->push_back(Expression::make_func_code_reference(no, bloc));

  ++p;
  go_assert(p == fields->end());

  return Expression::make_struct_composite_literal(method_type, vals, bloc);
}

// Return a composite literal for the type descriptor of a plain type.
// RUNTIME_TYPE_KIND is the value of the kind field.  If NAME is not
// NULL, it is the name to use as well as the list of methods.

Expression*
Type::plain_type_descriptor(Gogo* gogo, int runtime_type_kind,
			    Named_type* name)
{
  return this->type_descriptor_constructor(gogo, runtime_type_kind,
					   name, NULL, true);
}

// Return the type reflection string for this type.

std::string
Type::reflection(Gogo* gogo) const
{
  std::string ret;

  // The do_reflection virtual function should set RET to the
  // reflection string.
  this->do_reflection(gogo, &ret);

  return ret;
}

// Return whether the backend size of the type is known.

bool
Type::is_backend_type_size_known(Gogo* gogo)
{
  switch (this->classification_)
    {
    case TYPE_ERROR:
    case TYPE_VOID:
    case TYPE_BOOLEAN:
    case TYPE_INTEGER:
    case TYPE_FLOAT:
    case TYPE_COMPLEX:
    case TYPE_STRING:
    case TYPE_FUNCTION:
    case TYPE_POINTER:
    case TYPE_NIL:
    case TYPE_MAP:
    case TYPE_CHANNEL:
    case TYPE_INTERFACE:
      return true;

    case TYPE_STRUCT:
      {
	const Struct_field_list* fields = this->struct_type()->fields();
	for (Struct_field_list::const_iterator pf = fields->begin();
	     pf != fields->end();
	     ++pf)
	  if (!pf->type()->is_backend_type_size_known(gogo))
	    return false;
	return true;
      }

    case TYPE_ARRAY:
      {
	const Array_type* at = this->array_type();
	if (at->length() == NULL)
	  return true;
	else
	  {
	    Numeric_constant nc;
	    if (!at->length()->numeric_constant_value(&nc))
	      return false;
	    mpz_t ival;
	    if (!nc.to_int(&ival))
	      return false;
	    mpz_clear(ival);
	    return at->element_type()->is_backend_type_size_known(gogo);
	  }
      }

    case TYPE_NAMED:
      this->named_type()->convert(gogo);
      return this->named_type()->is_named_backend_type_size_known();

    case TYPE_FORWARD:
      {
	Forward_declaration_type* fdt = this->forward_declaration_type();
	return fdt->real_type()->is_backend_type_size_known(gogo);
      }

    case TYPE_SINK:
    case TYPE_CALL_MULTIPLE_RESULT:
      go_unreachable();

    default:
      go_unreachable();
    }
}

// If the size of the type can be determined, set *PSIZE to the size
// in bytes and return true.  Otherwise, return false.  This queries
// the backend.

bool
Type::backend_type_size(Gogo* gogo, int64_t *psize)
{
  if (!this->is_backend_type_size_known(gogo))
    return false;
  if (this->is_error_type())
    return false;
  Btype* bt = this->get_backend_placeholder(gogo);
  *psize = gogo->backend()->type_size(bt);
  if (*psize == -1)
    {
      if (this->named_type() != NULL)
	go_error_at(this->named_type()->location(),
		 "type %s larger than address space",
		 Gogo::message_name(this->named_type()->name()).c_str());
      else
	go_error_at(Linemap::unknown_location(),
		    "type %s larger than address space",
		    this->reflection(gogo).c_str());

      // Make this an error type to avoid knock-on errors.
      this->classification_ = TYPE_ERROR;
      return false;
    }
  return true;
}

// If the alignment of the type can be determined, set *PALIGN to
// the alignment in bytes and return true.  Otherwise, return false.

bool
Type::backend_type_align(Gogo* gogo, int64_t *palign)
{
  if (!this->is_backend_type_size_known(gogo))
    return false;
  Btype* bt = this->get_backend_placeholder(gogo);
  *palign = gogo->backend()->type_alignment(bt);
  return true;
}

// Like backend_type_align, but return the alignment when used as a
// field.

bool
Type::backend_type_field_align(Gogo* gogo, int64_t *palign)
{
  if (!this->is_backend_type_size_known(gogo))
    return false;
  Btype* bt = this->get_backend_placeholder(gogo);
  *palign = gogo->backend()->type_field_alignment(bt);
  return true;
}

// Get the ptrdata value for a type.  This is the size of the prefix
// of the type that contains all pointers.  Store the ptrdata in
// *PPTRDATA and return whether we found it.

bool
Type::backend_type_ptrdata(Gogo* gogo, int64_t* pptrdata)
{
  *pptrdata = 0;

  if (!this->has_pointer())
    return true;

  if (!this->is_backend_type_size_known(gogo))
    return false;

  switch (this->classification_)
    {
    case TYPE_ERROR:
      return true;

    case TYPE_FUNCTION:
    case TYPE_POINTER:
    case TYPE_MAP:
    case TYPE_CHANNEL:
      // These types are nothing but a pointer.
      return this->backend_type_size(gogo, pptrdata);

    case TYPE_INTERFACE:
      // An interface is a struct of two pointers.
      return this->backend_type_size(gogo, pptrdata);

    case TYPE_STRING:
      {
	// A string is a struct whose first field is a pointer, and
	// whose second field is not.
	Type* uint8_type = Type::lookup_integer_type("uint8");
	Type* ptr = Type::make_pointer_type(uint8_type);
	return ptr->backend_type_size(gogo, pptrdata);
      }

    case TYPE_NAMED:
    case TYPE_FORWARD:
      return this->base()->backend_type_ptrdata(gogo, pptrdata);

    case TYPE_STRUCT:
      {
	const Struct_field_list* fields = this->struct_type()->fields();
	int64_t offset = 0;
	const Struct_field *ptr = NULL;
	int64_t ptr_offset = 0;
	for (Struct_field_list::const_iterator pf = fields->begin();
	     pf != fields->end();
	     ++pf)
	  {
	    int64_t field_align;
	    if (!pf->type()->backend_type_field_align(gogo, &field_align))
	      return false;
	    offset = (offset + (field_align - 1)) &~ (field_align - 1);

	    if (pf->type()->has_pointer())
	      {
		ptr = &*pf;
		ptr_offset = offset;
	      }

	    int64_t field_size;
	    if (!pf->type()->backend_type_size(gogo, &field_size))
	      return false;
	    offset += field_size;
	  }

	if (ptr != NULL)
	  {
	    int64_t ptr_ptrdata;
	    if (!ptr->type()->backend_type_ptrdata(gogo, &ptr_ptrdata))
	      return false;
	    *pptrdata = ptr_offset + ptr_ptrdata;
	  }
	return true;
      }

    case TYPE_ARRAY:
      if (this->is_slice_type())
	{
	  // A slice is a struct whose first field is a pointer, and
	  // whose remaining fields are not.
	  Type* element_type = this->array_type()->element_type();
	  Type* ptr = Type::make_pointer_type(element_type);
	  return ptr->backend_type_size(gogo, pptrdata);
	}
      else
	{
	  Numeric_constant nc;
	  if (!this->array_type()->length()->numeric_constant_value(&nc))
	    return false;
	  int64_t len;
	  if (!nc.to_memory_size(&len))
	    return false;

	  Type* element_type = this->array_type()->element_type();
	  int64_t ele_size;
	  int64_t ele_ptrdata;
	  if (!element_type->backend_type_size(gogo, &ele_size)
	      || !element_type->backend_type_ptrdata(gogo, &ele_ptrdata))
	    return false;
	  go_assert(ele_size > 0 && ele_ptrdata > 0);

	  *pptrdata = (len - 1) * ele_size + ele_ptrdata;
	  return true;
	}

    default:
    case TYPE_VOID:
    case TYPE_BOOLEAN:
    case TYPE_INTEGER:
    case TYPE_FLOAT:
    case TYPE_COMPLEX:
    case TYPE_SINK:
    case TYPE_NIL:
    case TYPE_CALL_MULTIPLE_RESULT:
      go_unreachable();
    }
}

// Get the ptrdata value to store in a type descriptor.  This is
// normally the same as backend_type_ptrdata, but for a type that is
// large enough to use a gcprog we may need to store a different value
// if it ends with an array.  If the gcprog uses a repeat descriptor
// for the array, and if the array element ends with non-pointer data,
// then the gcprog will produce a value that describes the complete
// array where the backend ptrdata will omit the non-pointer elements
// of the final array element.  This is a subtle difference but the
// run time code checks it to verify that it has expanded a gcprog as
// expected.

bool
Type::descriptor_ptrdata(Gogo* gogo, int64_t* pptrdata)
{
  int64_t backend_ptrdata;
  if (!this->backend_type_ptrdata(gogo, &backend_ptrdata))
    return false;

  int64_t ptrsize;
  if (!this->needs_gcprog(gogo, &ptrsize, &backend_ptrdata))
    {
      *pptrdata = backend_ptrdata;
      return true;
    }

  GCProg prog;
  prog.set_from(gogo, this, ptrsize, 0);
  int64_t offset = prog.bit_index() * ptrsize;

  go_assert(offset >= backend_ptrdata);
  *pptrdata = offset;
  return true;
}

// Default function to export a type.

void
Type::do_export(Export*) const
{
  go_unreachable();
}

// Import a type.

Type*
Type::import_type(Import* imp)
{
  if (imp->match_c_string("("))
    return Function_type::do_import(imp);
  else if (imp->match_c_string("*"))
    return Pointer_type::do_import(imp);
  else if (imp->match_c_string("struct "))
    return Struct_type::do_import(imp);
  else if (imp->match_c_string("["))
    return Array_type::do_import(imp);
  else if (imp->match_c_string("map "))
    return Map_type::do_import(imp);
  else if (imp->match_c_string("chan "))
    return Channel_type::do_import(imp);
  else if (imp->match_c_string("interface"))
    return Interface_type::do_import(imp);
  else
    {
      go_error_at(imp->location(), "import error: expected type");
      return Type::make_error_type();
    }
}

// Class Error_type.

// Return the backend representation of an Error type.

Btype*
Error_type::do_get_backend(Gogo* gogo)
{
  return gogo->backend()->error_type();
}

// Return an expression for the type descriptor for an error type.


Expression*
Error_type::do_type_descriptor(Gogo*, Named_type*)
{
  return Expression::make_error(Linemap::predeclared_location());
}

// We should not be asked for the reflection string for an error type.

void
Error_type::do_reflection(Gogo*, std::string*) const
{
  go_assert(saw_errors());
}

Type*
Type::make_error_type()
{
  static Error_type singleton_error_type;
  return &singleton_error_type;
}

// Class Void_type.

// Get the backend representation of a void type.

Btype*
Void_type::do_get_backend(Gogo* gogo)
{
  return gogo->backend()->void_type();
}

Type*
Type::make_void_type()
{
  static Void_type singleton_void_type;
  return &singleton_void_type;
}

// Class Boolean_type.

// Return the backend representation of the boolean type.

Btype*
Boolean_type::do_get_backend(Gogo* gogo)
{
  return gogo->backend()->bool_type();
}

// Make the type descriptor.

Expression*
Boolean_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  if (name != NULL)
    return this->plain_type_descriptor(gogo, RUNTIME_TYPE_KIND_BOOL, name);
  else
    {
      Named_object* no = gogo->lookup_global("bool");
      go_assert(no != NULL);
      return Type::type_descriptor(gogo, no->type_value());
    }
}

Type*
Type::make_boolean_type()
{
  static Boolean_type boolean_type;
  return &boolean_type;
}

// The named type "bool".

static Named_type* named_bool_type;

// Get the named type "bool".

Named_type*
Type::lookup_bool_type()
{
  return named_bool_type;
}

// Make the named type "bool".

Named_type*
Type::make_named_bool_type()
{
  Type* bool_type = Type::make_boolean_type();
  Named_object* named_object =
    Named_object::make_type("bool", NULL, bool_type,
                            Linemap::predeclared_location());
  Named_type* named_type = named_object->type_value();
  named_bool_type = named_type;
  return named_type;
}

// Class Integer_type.

Integer_type::Named_integer_types Integer_type::named_integer_types;

// Create a new integer type.  Non-abstract integer types always have
// names.

Named_type*
Integer_type::create_integer_type(const char* name, bool is_unsigned,
				  int bits, int runtime_type_kind)
{
  Integer_type* integer_type = new Integer_type(false, is_unsigned, bits,
						runtime_type_kind);
  std::string sname(name);
  Named_object* named_object =
    Named_object::make_type(sname, NULL, integer_type,
                            Linemap::predeclared_location());
  Named_type* named_type = named_object->type_value();
  std::pair<Named_integer_types::iterator, bool> ins =
    Integer_type::named_integer_types.insert(std::make_pair(sname, named_type));
  go_assert(ins.second);
  return named_type;
}

// Look up an existing integer type.

Named_type*
Integer_type::lookup_integer_type(const char* name)
{
  Named_integer_types::const_iterator p =
    Integer_type::named_integer_types.find(name);
  go_assert(p != Integer_type::named_integer_types.end());
  return p->second;
}

// Create a new abstract integer type.

Integer_type*
Integer_type::create_abstract_integer_type()
{
  static Integer_type* abstract_type;
  if (abstract_type == NULL)
    {
      Type* int_type = Type::lookup_integer_type("int");
      abstract_type = new Integer_type(true, false,
				       int_type->integer_type()->bits(),
				       RUNTIME_TYPE_KIND_INT);
    }
  return abstract_type;
}

// Create a new abstract character type.

Integer_type*
Integer_type::create_abstract_character_type()
{
  static Integer_type* abstract_type;
  if (abstract_type == NULL)
    {
      abstract_type = new Integer_type(true, false, 32,
				       RUNTIME_TYPE_KIND_INT32);
      abstract_type->set_is_rune();
    }
  return abstract_type;
}

// Integer type compatibility.

bool
Integer_type::is_identical(const Integer_type* t) const
{
  if (this->is_unsigned_ != t->is_unsigned_ || this->bits_ != t->bits_)
    return false;
  return this->is_abstract_ == t->is_abstract_;
}

// Hash code.

unsigned int
Integer_type::do_hash_for_method(Gogo*, int) const
{
  return ((this->bits_ << 4)
	  + ((this->is_unsigned_ ? 1 : 0) << 8)
	  + ((this->is_abstract_ ? 1 : 0) << 9));
}

// Convert an Integer_type to the backend representation.

Btype*
Integer_type::do_get_backend(Gogo* gogo)
{
  if (this->is_abstract_)
    {
      go_assert(saw_errors());
      return gogo->backend()->error_type();
    }
  return gogo->backend()->integer_type(this->is_unsigned_, this->bits_);
}

// The type descriptor for an integer type.  Integer types are always
// named.

Expression*
Integer_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  go_assert(name != NULL || saw_errors());
  return this->plain_type_descriptor(gogo, this->runtime_type_kind_, name);
}

// We should not be asked for the reflection string of a basic type.

void
Integer_type::do_reflection(Gogo*, std::string*) const
{
  go_assert(saw_errors());
}

// Make an integer type.

Named_type*
Type::make_integer_type(const char* name, bool is_unsigned, int bits,
			int runtime_type_kind)
{
  return Integer_type::create_integer_type(name, is_unsigned, bits,
					   runtime_type_kind);
}

// Make an abstract integer type.

Integer_type*
Type::make_abstract_integer_type()
{
  return Integer_type::create_abstract_integer_type();
}

// Make an abstract character type.

Integer_type*
Type::make_abstract_character_type()
{
  return Integer_type::create_abstract_character_type();
}

// Look up an integer type.

Named_type*
Type::lookup_integer_type(const char* name)
{
  return Integer_type::lookup_integer_type(name);
}

// Class Float_type.

Float_type::Named_float_types Float_type::named_float_types;

// Create a new float type.  Non-abstract float types always have
// names.

Named_type*
Float_type::create_float_type(const char* name, int bits,
			      int runtime_type_kind)
{
  Float_type* float_type = new Float_type(false, bits, runtime_type_kind);
  std::string sname(name);
  Named_object* named_object =
    Named_object::make_type(sname, NULL, float_type,
                            Linemap::predeclared_location());
  Named_type* named_type = named_object->type_value();
  std::pair<Named_float_types::iterator, bool> ins =
    Float_type::named_float_types.insert(std::make_pair(sname, named_type));
  go_assert(ins.second);
  return named_type;
}

// Look up an existing float type.

Named_type*
Float_type::lookup_float_type(const char* name)
{
  Named_float_types::const_iterator p =
    Float_type::named_float_types.find(name);
  go_assert(p != Float_type::named_float_types.end());
  return p->second;
}

// Create a new abstract float type.

Float_type*
Float_type::create_abstract_float_type()
{
  static Float_type* abstract_type;
  if (abstract_type == NULL)
    abstract_type = new Float_type(true, 64, RUNTIME_TYPE_KIND_FLOAT64);
  return abstract_type;
}

// Whether this type is identical with T.

bool
Float_type::is_identical(const Float_type* t) const
{
  if (this->bits_ != t->bits_)
    return false;
  return this->is_abstract_ == t->is_abstract_;
}

// Hash code.

unsigned int
Float_type::do_hash_for_method(Gogo*, int) const
{
  return (this->bits_ << 4) + ((this->is_abstract_ ? 1 : 0) << 8);
}

// Convert to the backend representation.

Btype*
Float_type::do_get_backend(Gogo* gogo)
{
  return gogo->backend()->float_type(this->bits_);
}

// The type descriptor for a float type.  Float types are always named.

Expression*
Float_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  go_assert(name != NULL || saw_errors());
  return this->plain_type_descriptor(gogo, this->runtime_type_kind_, name);
}

// We should not be asked for the reflection string of a basic type.

void
Float_type::do_reflection(Gogo*, std::string*) const
{
  go_assert(saw_errors());
}

// Make a floating point type.

Named_type*
Type::make_float_type(const char* name, int bits, int runtime_type_kind)
{
  return Float_type::create_float_type(name, bits, runtime_type_kind);
}

// Make an abstract float type.

Float_type*
Type::make_abstract_float_type()
{
  return Float_type::create_abstract_float_type();
}

// Look up a float type.

Named_type*
Type::lookup_float_type(const char* name)
{
  return Float_type::lookup_float_type(name);
}

// Class Complex_type.

Complex_type::Named_complex_types Complex_type::named_complex_types;

// Create a new complex type.  Non-abstract complex types always have
// names.

Named_type*
Complex_type::create_complex_type(const char* name, int bits,
				  int runtime_type_kind)
{
  Complex_type* complex_type = new Complex_type(false, bits,
						runtime_type_kind);
  std::string sname(name);
  Named_object* named_object =
    Named_object::make_type(sname, NULL, complex_type,
                            Linemap::predeclared_location());
  Named_type* named_type = named_object->type_value();
  std::pair<Named_complex_types::iterator, bool> ins =
    Complex_type::named_complex_types.insert(std::make_pair(sname,
							    named_type));
  go_assert(ins.second);
  return named_type;
}

// Look up an existing complex type.

Named_type*
Complex_type::lookup_complex_type(const char* name)
{
  Named_complex_types::const_iterator p =
    Complex_type::named_complex_types.find(name);
  go_assert(p != Complex_type::named_complex_types.end());
  return p->second;
}

// Create a new abstract complex type.

Complex_type*
Complex_type::create_abstract_complex_type()
{
  static Complex_type* abstract_type;
  if (abstract_type == NULL)
    abstract_type = new Complex_type(true, 128, RUNTIME_TYPE_KIND_COMPLEX128);
  return abstract_type;
}

// Whether this type is identical with T.

bool
Complex_type::is_identical(const Complex_type *t) const
{
  if (this->bits_ != t->bits_)
    return false;
  return this->is_abstract_ == t->is_abstract_;
}

// Hash code.

unsigned int
Complex_type::do_hash_for_method(Gogo*, int) const
{
  return (this->bits_ << 4) + ((this->is_abstract_ ? 1 : 0) << 8);
}

// Convert to the backend representation.

Btype*
Complex_type::do_get_backend(Gogo* gogo)
{
  return gogo->backend()->complex_type(this->bits_);
}

// The type descriptor for a complex type.  Complex types are always
// named.

Expression*
Complex_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  go_assert(name != NULL || saw_errors());
  return this->plain_type_descriptor(gogo, this->runtime_type_kind_, name);
}

// We should not be asked for the reflection string of a basic type.

void
Complex_type::do_reflection(Gogo*, std::string*) const
{
  go_assert(saw_errors());
}

// Make a complex type.

Named_type*
Type::make_complex_type(const char* name, int bits, int runtime_type_kind)
{
  return Complex_type::create_complex_type(name, bits, runtime_type_kind);
}

// Make an abstract complex type.

Complex_type*
Type::make_abstract_complex_type()
{
  return Complex_type::create_abstract_complex_type();
}

// Look up a complex type.

Named_type*
Type::lookup_complex_type(const char* name)
{
  return Complex_type::lookup_complex_type(name);
}

// Class String_type.

// Convert String_type to the backend representation.  A string is a
// struct with two fields: a pointer to the characters and a length.

Btype*
String_type::do_get_backend(Gogo* gogo)
{
  static Btype* backend_string_type;
  if (backend_string_type == NULL)
    {
      std::vector<Backend::Btyped_identifier> fields(2);

      Type* b = gogo->lookup_global("byte")->type_value();
      Type* pb = Type::make_pointer_type(b);

      // We aren't going to get back to this field to finish the
      // backend representation, so force it to be finished now.
      if (!gogo->named_types_are_converted())
	{
	  Btype* bt = pb->get_backend_placeholder(gogo);
	  pb->finish_backend(gogo, bt);
	}

      fields[0].name = "__data";
      fields[0].btype = pb->get_backend(gogo);
      fields[0].location = Linemap::predeclared_location();

      Type* int_type = Type::lookup_integer_type("int");
      fields[1].name = "__length";
      fields[1].btype = int_type->get_backend(gogo);
      fields[1].location = fields[0].location;

      backend_string_type = gogo->backend()->struct_type(fields);
    }
  return backend_string_type;
}

// The type descriptor for the string type.

Expression*
String_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  if (name != NULL)
    return this->plain_type_descriptor(gogo, RUNTIME_TYPE_KIND_STRING, name);
  else
    {
      Named_object* no = gogo->lookup_global("string");
      go_assert(no != NULL);
      return Type::type_descriptor(gogo, no->type_value());
    }
}

// We should not be asked for the reflection string of a basic type.

void
String_type::do_reflection(Gogo*, std::string* ret) const
{
  ret->append("string");
}

// Make a string type.

Type*
Type::make_string_type()
{
  static String_type string_type;
  return &string_type;
}

// The named type "string".

static Named_type* named_string_type;

// Get the named type "string".

Named_type*
Type::lookup_string_type()
{
  return named_string_type;
}

// Make the named type string.

Named_type*
Type::make_named_string_type()
{
  Type* string_type = Type::make_string_type();
  Named_object* named_object =
    Named_object::make_type("string", NULL, string_type,
                            Linemap::predeclared_location());
  Named_type* named_type = named_object->type_value();
  named_string_type = named_type;
  return named_type;
}

// The sink type.  This is the type of the blank identifier _.  Any
// type may be assigned to it.

class Sink_type : public Type
{
 public:
  Sink_type()
    : Type(TYPE_SINK)
  { }

 protected:
  bool
  do_compare_is_identity(Gogo*)
  { return false; }

  Btype*
  do_get_backend(Gogo*)
  { go_unreachable(); }

  Expression*
  do_type_descriptor(Gogo*, Named_type*)
  { go_unreachable(); }

  void
  do_reflection(Gogo*, std::string*) const
  { go_unreachable(); }

  void
  do_mangled_name(Gogo*, std::string*) const
  { go_unreachable(); }
};

// Make the sink type.

Type*
Type::make_sink_type()
{
  static Sink_type sink_type;
  return &sink_type;
}

// Class Function_type.

// Traversal.

int
Function_type::do_traverse(Traverse* traverse)
{
  if (this->receiver_ != NULL
      && Type::traverse(this->receiver_->type(), traverse) == TRAVERSE_EXIT)
    return TRAVERSE_EXIT;
  if (this->parameters_ != NULL
      && this->parameters_->traverse(traverse) == TRAVERSE_EXIT)
    return TRAVERSE_EXIT;
  if (this->results_ != NULL
      && this->results_->traverse(traverse) == TRAVERSE_EXIT)
    return TRAVERSE_EXIT;
  return TRAVERSE_CONTINUE;
}

// Returns whether T is a valid redeclaration of this type.  If this
// returns false, and REASON is not NULL, *REASON may be set to a
// brief explanation of why it returned false.

bool
Function_type::is_valid_redeclaration(const Function_type* t,
				      std::string* reason) const
{
  if (!this->is_identical(t, false, COMPARE_TAGS, reason))
    return false;

  // A redeclaration of a function is required to use the same names
  // for the receiver and parameters.
  if (this->receiver() != NULL
      && this->receiver()->name() != t->receiver()->name())
    {
      if (reason != NULL)
	*reason = "receiver name changed";
      return false;
    }

  const Typed_identifier_list* parms1 = this->parameters();
  const Typed_identifier_list* parms2 = t->parameters();
  if (parms1 != NULL)
    {
      Typed_identifier_list::const_iterator p1 = parms1->begin();
      for (Typed_identifier_list::const_iterator p2 = parms2->begin();
	   p2 != parms2->end();
	   ++p2, ++p1)
	{
	  if (p1->name() != p2->name())
	    {
	      if (reason != NULL)
		*reason = "parameter name changed";
	      return false;
	    }

	  // This is called at parse time, so we may have unknown
	  // types.
	  Type* t1 = p1->type()->forwarded();
	  Type* t2 = p2->type()->forwarded();
	  if (t1 != t2
	      && t1->forward_declaration_type() != NULL
	      && (t2->forward_declaration_type() == NULL
		  || (t1->forward_declaration_type()->named_object()
		      != t2->forward_declaration_type()->named_object())))
	    return false;
	}
    }

  const Typed_identifier_list* results1 = this->results();
  const Typed_identifier_list* results2 = t->results();
  if (results1 != NULL)
    {
      Typed_identifier_list::const_iterator res1 = results1->begin();
      for (Typed_identifier_list::const_iterator res2 = results2->begin();
	   res2 != results2->end();
	   ++res2, ++res1)
	{
	  if (res1->name() != res2->name())
	    {
	      if (reason != NULL)
		*reason = "result name changed";
	      return false;
	    }

	  // This is called at parse time, so we may have unknown
	  // types.
	  Type* t1 = res1->type()->forwarded();
	  Type* t2 = res2->type()->forwarded();
	  if (t1 != t2
	      && t1->forward_declaration_type() != NULL
	      && (t2->forward_declaration_type() == NULL
		  || (t1->forward_declaration_type()->named_object()
		      != t2->forward_declaration_type()->named_object())))
	    return false;
	}
    }

  return true;
}

// Check whether T is the same as this type.

bool
Function_type::is_identical(const Function_type* t, bool ignore_receiver,
			    int flags, std::string* reason) const
{
  if (this->is_backend_function_type() != t->is_backend_function_type())
    return false;

  if (!ignore_receiver)
    {
      const Typed_identifier* r1 = this->receiver();
      const Typed_identifier* r2 = t->receiver();
      if ((r1 != NULL) != (r2 != NULL))
	{
	  if (reason != NULL)
	    *reason = _("different receiver types");
	  return false;
	}
      if (r1 != NULL)
	{
	  if (!Type::are_identical(r1->type(), r2->type(), flags, reason))
	    {
	      if (reason != NULL && !reason->empty())
		*reason = "receiver: " + *reason;
	      return false;
	    }
	}
    }

  const Typed_identifier_list* parms1 = this->parameters();
  if (parms1 != NULL && parms1->empty())
    parms1 = NULL;
  const Typed_identifier_list* parms2 = t->parameters();
  if (parms2 != NULL && parms2->empty())
    parms2 = NULL;
  if ((parms1 != NULL) != (parms2 != NULL))
    {
      if (reason != NULL)
	*reason = _("different number of parameters");
      return false;
    }
  if (parms1 != NULL)
    {
      Typed_identifier_list::const_iterator p1 = parms1->begin();
      for (Typed_identifier_list::const_iterator p2 = parms2->begin();
	   p2 != parms2->end();
	   ++p2, ++p1)
	{
	  if (p1 == parms1->end())
	    {
	      if (reason != NULL)
		*reason = _("different number of parameters");
	      return false;
	    }

	  if (!Type::are_identical(p1->type(), p2->type(), flags, NULL))
	    {
	      if (reason != NULL)
		*reason = _("different parameter types");
	      return false;
	    }
	}
      if (p1 != parms1->end())
	{
	  if (reason != NULL)
	    *reason = _("different number of parameters");
	return false;
	}
    }

  if (this->is_varargs() != t->is_varargs())
    {
      if (reason != NULL)
	*reason = _("different varargs");
      return false;
    }

  const Typed_identifier_list* results1 = this->results();
  if (results1 != NULL && results1->empty())
    results1 = NULL;
  const Typed_identifier_list* results2 = t->results();
  if (results2 != NULL && results2->empty())
    results2 = NULL;
  if ((results1 != NULL) != (results2 != NULL))
    {
      if (reason != NULL)
	*reason = _("different number of results");
      return false;
    }
  if (results1 != NULL)
    {
      Typed_identifier_list::const_iterator res1 = results1->begin();
      for (Typed_identifier_list::const_iterator res2 = results2->begin();
	   res2 != results2->end();
	   ++res2, ++res1)
	{
	  if (res1 == results1->end())
	    {
	      if (reason != NULL)
		*reason = _("different number of results");
	      return false;
	    }

	  if (!Type::are_identical(res1->type(), res2->type(), flags, NULL))
	    {
	      if (reason != NULL)
		*reason = _("different result types");
	      return false;
	    }
	}
      if (res1 != results1->end())
	{
	  if (reason != NULL)
	    *reason = _("different number of results");
	  return false;
	}
    }

  return true;
}

// Hash code.

unsigned int
Function_type::do_hash_for_method(Gogo* gogo, int flags) const
{
  unsigned int ret = 0;
  // We ignore the receiver type for hash codes, because we need to
  // get the same hash code for a method in an interface and a method
  // declared for a type.  The former will not have a receiver.
  if (this->parameters_ != NULL)
    {
      int shift = 1;
      for (Typed_identifier_list::const_iterator p = this->parameters_->begin();
	   p != this->parameters_->end();
	   ++p, ++shift)
	ret += p->type()->hash_for_method(gogo, flags) << shift;
    }
  if (this->results_ != NULL)
    {
      int shift = 2;
      for (Typed_identifier_list::const_iterator p = this->results_->begin();
	   p != this->results_->end();
	   ++p, ++shift)
	ret += p->type()->hash_for_method(gogo, flags) << shift;
    }
  if (this->is_varargs_)
    ret += 1;
  ret <<= 4;
  return ret;
}

// Hash result parameters.

unsigned int
Function_type::Results_hash::operator()(const Typed_identifier_list* t) const
{
  unsigned int hash = 0;
  for (Typed_identifier_list::const_iterator p = t->begin();
       p != t->end();
       ++p)
    {
      hash <<= 2;
      hash = Type::hash_string(p->name(), hash);
      hash += p->type()->hash_for_method(NULL, Type::COMPARE_TAGS);
    }
  return hash;
}

// Compare result parameters so that can map identical result
// parameters to a single struct type.

bool
Function_type::Results_equal::operator()(const Typed_identifier_list* a,
					 const Typed_identifier_list* b) const
{
  if (a->size() != b->size())
    return false;
  Typed_identifier_list::const_iterator pa = a->begin();
  for (Typed_identifier_list::const_iterator pb = b->begin();
       pb != b->end();
       ++pa, ++pb)
    {
      if (pa->name() != pb->name()
	  || !Type::are_identical(pa->type(), pb->type(), Type::COMPARE_TAGS,
				  NULL))
	return false;
    }
  return true;
}

// Hash from results to a backend struct type.

Function_type::Results_structs Function_type::results_structs;

// Get the backend representation for a function type.

Btype*
Function_type::get_backend_fntype(Gogo* gogo)
{
  if (this->fnbtype_ == NULL)
    {
      Backend::Btyped_identifier breceiver;
      if (this->receiver_ != NULL)
        {
          breceiver.name = Gogo::unpack_hidden_name(this->receiver_->name());

          // We always pass the address of the receiver parameter, in
          // order to make interface calls work with unknown types.
          Type* rtype = this->receiver_->type();
          if (rtype->points_to() == NULL)
            rtype = Type::make_pointer_type(rtype);
          breceiver.btype = rtype->get_backend(gogo);
          breceiver.location = this->receiver_->location();
        }

      std::vector<Backend::Btyped_identifier> bparameters;
      if (this->parameters_ != NULL)
        {
          bparameters.resize(this->parameters_->size());
          size_t i = 0;
          for (Typed_identifier_list::const_iterator p =
                   this->parameters_->begin(); p != this->parameters_->end();
               ++p, ++i)
	    {
              bparameters[i].name = Gogo::unpack_hidden_name(p->name());
              bparameters[i].btype = p->type()->get_backend(gogo);
              bparameters[i].location = p->location();
            }
          go_assert(i == bparameters.size());
        }

      std::vector<Backend::Btyped_identifier> bresults;
      Btype* bresult_struct = NULL;
      if (this->results_ != NULL)
        {
          bresults.resize(this->results_->size());
          size_t i = 0;
          for (Typed_identifier_list::const_iterator p =
                   this->results_->begin();
	       p != this->results_->end();
               ++p, ++i)
	    {
              bresults[i].name = Gogo::unpack_hidden_name(p->name());
              bresults[i].btype = p->type()->get_backend(gogo);
              bresults[i].location = p->location();
            }
          go_assert(i == bresults.size());

	  if (this->results_->size() > 1)
	    {
	      // Use the same results struct for all functions that
	      // return the same set of results.  This is useful to
	      // unify calls to interface methods with other calls.
	      std::pair<Typed_identifier_list*, Btype*> val;
	      val.first = this->results_;
	      val.second = NULL;
	      std::pair<Results_structs::iterator, bool> ins =
		Function_type::results_structs.insert(val);
	      if (ins.second)
		{
		  // Build a new struct type.
		  Struct_field_list* sfl = new Struct_field_list;
		  for (Typed_identifier_list::const_iterator p =
			 this->results_->begin();
		       p != this->results_->end();
		       ++p)
		    {
		      Typed_identifier tid = *p;
		      if (tid.name().empty())
			tid = Typed_identifier("UNNAMED", tid.type(),
					       tid.location());
		      sfl->push_back(Struct_field(tid));
		    }
		  Struct_type* st = Type::make_struct_type(sfl,
							   this->location());
		  st->set_is_struct_incomparable();
		  ins.first->second = st->get_backend(gogo);
		}
	      bresult_struct = ins.first->second;
	    }
        }

      this->fnbtype_ = gogo->backend()->function_type(breceiver, bparameters,
                                                      bresults, bresult_struct,
                                                      this->location());

    }

  return this->fnbtype_;
}

// Get the backend representation for a Go function type.

Btype*
Function_type::do_get_backend(Gogo* gogo)
{
  // When we do anything with a function value other than call it, it
  // is represented as a pointer to a struct whose first field is the
  // actual function.  So that is what we return as the type of a Go
  // function.

  Location loc = this->location();
  Btype* struct_type =
    gogo->backend()->placeholder_struct_type("__go_descriptor", loc);
  Btype* ptr_struct_type = gogo->backend()->pointer_type(struct_type);

  std::vector<Backend::Btyped_identifier> fields(1);
  fields[0].name = "code";
  fields[0].btype = this->get_backend_fntype(gogo);
  fields[0].location = loc;
  if (!gogo->backend()->set_placeholder_struct_type(struct_type, fields))
    return gogo->backend()->error_type();
  return ptr_struct_type;
}

// The type of a function type descriptor.

Type*
Function_type::make_function_type_descriptor_type()
{
  static Type* ret;
  if (ret == NULL)
    {
      Type* tdt = Type::make_type_descriptor_type();
      Type* ptdt = Type::make_type_descriptor_ptr_type();

      Type* bool_type = Type::lookup_bool_type();

      Type* slice_type = Type::make_array_type(ptdt, NULL);

      Struct_type* s = Type::make_builtin_struct_type(4,
						      "", tdt,
						      "dotdotdot", bool_type,
						      "in", slice_type,
						      "out", slice_type);

      ret = Type::make_builtin_named_type("FuncType", s);
    }

  return ret;
}

// The type descriptor for a function type.

Expression*
Function_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  Location bloc = Linemap::predeclared_location();

  Type* ftdt = Function_type::make_function_type_descriptor_type();

  const Struct_field_list* fields = ftdt->struct_type()->fields();

  Expression_list* vals = new Expression_list();
  vals->reserve(4);

  Struct_field_list::const_iterator p = fields->begin();
  go_assert(p->is_field_name("_type"));
  vals->push_back(this->type_descriptor_constructor(gogo,
						    RUNTIME_TYPE_KIND_FUNC,
						    name, NULL, true));

  ++p;
  go_assert(p->is_field_name("dotdotdot"));
  vals->push_back(Expression::make_boolean(this->is_varargs(), bloc));

  ++p;
  go_assert(p->is_field_name("in"));
  vals->push_back(this->type_descriptor_params(p->type(), this->receiver(),
					       this->parameters()));

  ++p;
  go_assert(p->is_field_name("out"));
  vals->push_back(this->type_descriptor_params(p->type(), NULL,
					       this->results()));

  ++p;
  go_assert(p == fields->end());

  return Expression::make_struct_composite_literal(ftdt, vals, bloc);
}

// Return a composite literal for the parameters or results of a type
// descriptor.

Expression*
Function_type::type_descriptor_params(Type* params_type,
				      const Typed_identifier* receiver,
				      const Typed_identifier_list* params)
{
  Location bloc = Linemap::predeclared_location();

  if (receiver == NULL && params == NULL)
    return Expression::make_slice_composite_literal(params_type, NULL, bloc);

  Expression_list* vals = new Expression_list();
  vals->reserve((params == NULL ? 0 : params->size())
		+ (receiver != NULL ? 1 : 0));

  if (receiver != NULL)
    vals->push_back(Expression::make_type_descriptor(receiver->type(), bloc));

  if (params != NULL)
    {
      for (Typed_identifier_list::const_iterator p = params->begin();
	   p != params->end();
	   ++p)
	vals->push_back(Expression::make_type_descriptor(p->type(), bloc));
    }

  return Expression::make_slice_composite_literal(params_type, vals, bloc);
}

// The reflection string.

void
Function_type::do_reflection(Gogo* gogo, std::string* ret) const
{
  // FIXME: Turn this off until we straighten out the type of the
  // struct field used in a go statement which calls a method.
  // go_assert(this->receiver_ == NULL);

  ret->append("func");

  if (this->receiver_ != NULL)
    {
      ret->push_back('(');
      this->append_reflection(this->receiver_->type(), gogo, ret);
      ret->push_back(')');
    }

  ret->push_back('(');
  const Typed_identifier_list* params = this->parameters();
  if (params != NULL)
    {
      bool is_varargs = this->is_varargs_;
      for (Typed_identifier_list::const_iterator p = params->begin();
	   p != params->end();
	   ++p)
	{
	  if (p != params->begin())
	    ret->append(", ");
	  if (!is_varargs || p + 1 != params->end())
	    this->append_reflection(p->type(), gogo, ret);
	  else
	    {
	      ret->append("...");
	      this->append_reflection(p->type()->array_type()->element_type(),
				      gogo, ret);
	    }
	}
    }
  ret->push_back(')');

  const Typed_identifier_list* results = this->results();
  if (results != NULL && !results->empty())
    {
      if (results->size() == 1)
	ret->push_back(' ');
      else
	ret->append(" (");
      for (Typed_identifier_list::const_iterator p = results->begin();
	   p != results->end();
	   ++p)
	{
	  if (p != results->begin())
	    ret->append(", ");
	  this->append_reflection(p->type(), gogo, ret);
	}
      if (results->size() > 1)
	ret->push_back(')');
    }
}

// Export a function type.

void
Function_type::do_export(Export* exp) const
{
  // We don't write out the receiver.  The only function types which
  // should have a receiver are the ones associated with explicitly
  // defined methods.  For those the receiver type is written out by
  // Function::export_func.

  exp->write_c_string("(");
  bool first = true;
  if (this->parameters_ != NULL)
    {
      bool is_varargs = this->is_varargs_;
      for (Typed_identifier_list::const_iterator p =
	     this->parameters_->begin();
	   p != this->parameters_->end();
	   ++p)
	{
	  if (first)
	    first = false;
	  else
	    exp->write_c_string(", ");
	  exp->write_name(p->name());
	  exp->write_c_string(" ");
	  if (!is_varargs || p + 1 != this->parameters_->end())
	    exp->write_type(p->type());
	  else
	    {
	      exp->write_c_string("...");
	      exp->write_type(p->type()->array_type()->element_type());
	    }
	}
    }
  exp->write_c_string(")");

  const Typed_identifier_list* results = this->results_;
  if (results != NULL)
    {
      exp->write_c_string(" ");
      if (results->size() == 1 && results->begin()->name().empty())
	exp->write_type(results->begin()->type());
      else
	{
	  first = true;
	  exp->write_c_string("(");
	  for (Typed_identifier_list::const_iterator p = results->begin();
	       p != results->end();
	       ++p)
	    {
	      if (first)
		first = false;
	      else
		exp->write_c_string(", ");
	      exp->write_name(p->name());
	      exp->write_c_string(" ");
	      exp->write_type(p->type());
	    }
	  exp->write_c_string(")");
	}
    }
}

// Import a function type.

Function_type*
Function_type::do_import(Import* imp)
{
  imp->require_c_string("(");
  Typed_identifier_list* parameters;
  bool is_varargs = false;
  if (imp->peek_char() == ')')
    parameters = NULL;
  else
    {
      parameters = new Typed_identifier_list();
      while (true)
	{
	  std::string name = imp->read_name();
	  imp->require_c_string(" ");

	  if (imp->match_c_string("..."))
	    {
	      imp->advance(3);
	      is_varargs = true;
	    }

	  Type* ptype = imp->read_type();
	  if (is_varargs)
	    ptype = Type::make_array_type(ptype, NULL);
	  parameters->push_back(Typed_identifier(name, ptype,
						 imp->location()));
	  if (imp->peek_char() != ',')
	    break;
	  go_assert(!is_varargs);
	  imp->require_c_string(", ");
	}
    }
  imp->require_c_string(")");

  Typed_identifier_list* results;
  if (imp->peek_char() != ' ')
    results = NULL;
  else
    {
      imp->advance(1);
      results = new Typed_identifier_list;
      if (imp->peek_char() != '(')
	{
	  Type* rtype = imp->read_type();
	  results->push_back(Typed_identifier("", rtype, imp->location()));
	}
      else
	{
	  imp->advance(1);
	  while (true)
	    {
	      std::string name = imp->read_name();
	      imp->require_c_string(" ");
	      Type* rtype = imp->read_type();
	      results->push_back(Typed_identifier(name, rtype,
						  imp->location()));
	      if (imp->peek_char() != ',')
		break;
	      imp->require_c_string(", ");
	    }
	  imp->require_c_string(")");
	}
    }

  Function_type* ret = Type::make_function_type(NULL, parameters, results,
						imp->location());
  if (is_varargs)
    ret->set_is_varargs();
  return ret;
}

// Make a copy of a function type without a receiver.

Function_type*
Function_type::copy_without_receiver() const
{
  go_assert(this->is_method());
  Function_type *ret = Type::make_function_type(NULL, this->parameters_,
						this->results_,
						this->location_);
  if (this->is_varargs())
    ret->set_is_varargs();
  if (this->is_builtin())
    ret->set_is_builtin();
  return ret;
}

// Make a copy of a function type with a receiver.

Function_type*
Function_type::copy_with_receiver(Type* receiver_type) const
{
  go_assert(!this->is_method());
  Typed_identifier* receiver = new Typed_identifier("", receiver_type,
						    this->location_);
  Function_type* ret = Type::make_function_type(receiver, this->parameters_,
						this->results_,
						this->location_);
  if (this->is_varargs_)
    ret->set_is_varargs();
  return ret;
}

// Make a copy of a function type with the receiver as the first
// parameter.

Function_type*
Function_type::copy_with_receiver_as_param(bool want_pointer_receiver) const
{
  go_assert(this->is_method());
  Typed_identifier_list* new_params = new Typed_identifier_list();
  Type* rtype = this->receiver_->type();
  if (want_pointer_receiver)
    rtype = Type::make_pointer_type(rtype);
  Typed_identifier receiver(this->receiver_->name(), rtype,
			    this->receiver_->location());
  new_params->push_back(receiver);
  const Typed_identifier_list* orig_params = this->parameters_;
  if (orig_params != NULL && !orig_params->empty())
    {
      for (Typed_identifier_list::const_iterator p = orig_params->begin();
	   p != orig_params->end();
	   ++p)
	new_params->push_back(*p);
    }
  return Type::make_function_type(NULL, new_params, this->results_,
				  this->location_);
}

// Make a copy of a function type ignoring any receiver and adding a
// closure parameter.

Function_type*
Function_type::copy_with_names() const
{
  Typed_identifier_list* new_params = new Typed_identifier_list();
  const Typed_identifier_list* orig_params = this->parameters_;
  if (orig_params != NULL && !orig_params->empty())
    {
      static int count;
      char buf[50];
      for (Typed_identifier_list::const_iterator p = orig_params->begin();
	   p != orig_params->end();
	   ++p)
	{
	  snprintf(buf, sizeof buf, "pt.%u", count);
	  ++count;
	  new_params->push_back(Typed_identifier(buf, p->type(),
						 p->location()));
	}
    }

  const Typed_identifier_list* orig_results = this->results_;
  Typed_identifier_list* new_results;
  if (orig_results == NULL || orig_results->empty())
    new_results = NULL;
  else
    {
      new_results = new Typed_identifier_list();
      for (Typed_identifier_list::const_iterator p = orig_results->begin();
	   p != orig_results->end();
	   ++p)
	new_results->push_back(Typed_identifier("", p->type(),
						p->location()));
    }

  return Type::make_function_type(NULL, new_params, new_results,
				  this->location());
}

// Make a function type.

Function_type*
Type::make_function_type(Typed_identifier* receiver,
			 Typed_identifier_list* parameters,
			 Typed_identifier_list* results,
			 Location location)
{
  return new Function_type(receiver, parameters, results, location);
}

// Make a backend function type.

Backend_function_type*
Type::make_backend_function_type(Typed_identifier* receiver,
                                 Typed_identifier_list* parameters,
                                 Typed_identifier_list* results,
                                 Location location)
{
  return new Backend_function_type(receiver, parameters, results, location);
}

// Class Pointer_type.

// Traversal.

int
Pointer_type::do_traverse(Traverse* traverse)
{
  return Type::traverse(this->to_type_, traverse);
}

// Hash code.

unsigned int
Pointer_type::do_hash_for_method(Gogo* gogo, int flags) const
{
  return this->to_type_->hash_for_method(gogo, flags) << 4;
}

// Get the backend representation for a pointer type.

Btype*
Pointer_type::do_get_backend(Gogo* gogo)
{
  Btype* to_btype = this->to_type_->get_backend(gogo);
  return gogo->backend()->pointer_type(to_btype);
}

// The type of a pointer type descriptor.

Type*
Pointer_type::make_pointer_type_descriptor_type()
{
  static Type* ret;
  if (ret == NULL)
    {
      Type* tdt = Type::make_type_descriptor_type();
      Type* ptdt = Type::make_type_descriptor_ptr_type();

      Struct_type* s = Type::make_builtin_struct_type(2,
						      "", tdt,
						      "elem", ptdt);

      ret = Type::make_builtin_named_type("PtrType", s);
    }

  return ret;
}

// The type descriptor for a pointer type.

Expression*
Pointer_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  if (this->is_unsafe_pointer_type())
    {
      go_assert(name != NULL);
      return this->plain_type_descriptor(gogo,
					 RUNTIME_TYPE_KIND_UNSAFE_POINTER,
					 name);
    }
  else
    {
      Location bloc = Linemap::predeclared_location();

      const Methods* methods;
      Type* deref = this->points_to();
      if (deref->named_type() != NULL)
	methods = deref->named_type()->methods();
      else if (deref->struct_type() != NULL)
	methods = deref->struct_type()->methods();
      else
	methods = NULL;

      Type* ptr_tdt = Pointer_type::make_pointer_type_descriptor_type();

      const Struct_field_list* fields = ptr_tdt->struct_type()->fields();

      Expression_list* vals = new Expression_list();
      vals->reserve(2);

      Struct_field_list::const_iterator p = fields->begin();
      go_assert(p->is_field_name("_type"));
      vals->push_back(this->type_descriptor_constructor(gogo,
							RUNTIME_TYPE_KIND_PTR,
							name, methods, false));

      ++p;
      go_assert(p->is_field_name("elem"));
      vals->push_back(Expression::make_type_descriptor(deref, bloc));

      return Expression::make_struct_composite_literal(ptr_tdt, vals, bloc);
    }
}

// Reflection string.

void
Pointer_type::do_reflection(Gogo* gogo, std::string* ret) const
{
  ret->push_back('*');
  this->append_reflection(this->to_type_, gogo, ret);
}

// Export.

void
Pointer_type::do_export(Export* exp) const
{
  exp->write_c_string("*");
  if (this->is_unsafe_pointer_type())
    exp->write_c_string("any");
  else
    exp->write_type(this->to_type_);
}

// Import.

Pointer_type*
Pointer_type::do_import(Import* imp)
{
  imp->require_c_string("*");
  if (imp->match_c_string("any"))
    {
      imp->advance(3);
      return Type::make_pointer_type(Type::make_void_type());
    }
  Type* to = imp->read_type();
  return Type::make_pointer_type(to);
}

// Cache of pointer types. Key is "to" type, value is pointer type
// that points to key.

Type::Pointer_type_table Type::pointer_types;

// A list of placeholder pointer types.  We keep this so we can ensure
// they are finalized.

std::vector<Pointer_type*> Type::placeholder_pointers;

// Make a pointer type.

Pointer_type*
Type::make_pointer_type(Type* to_type)
{
  Pointer_type_table::const_iterator p = pointer_types.find(to_type);
  if (p != pointer_types.end())
    return p->second;
  Pointer_type* ret = new Pointer_type(to_type);
  pointer_types[to_type] = ret;
  return ret;
}

// This helper is invoked immediately after named types have been
// converted, to clean up any unresolved pointer types remaining in
// the pointer type cache.
//
// The motivation for this routine: occasionally the compiler creates
// some specific pointer type as part of a lowering operation (ex:
// pointer-to-void), then Type::backend_type_size() is invoked on the
// type (which creates a Btype placeholder for it), that placeholder
// passed somewhere along the line to the back end, but since there is
// no reference to the type in user code, there is never a call to
// Type::finish_backend for the type (hence the Btype remains as an
// unresolved placeholder).  Calling this routine will clean up such
// instances.

void
Type::finish_pointer_types(Gogo* gogo)
{
  // We don't use begin() and end() because it is possible to add new
  // placeholder pointer types as we finalized existing ones.
  for (size_t i = 0; i < Type::placeholder_pointers.size(); i++)
    {
      Pointer_type* pt = Type::placeholder_pointers[i];
      Type_btypes::iterator tbti = Type::type_btypes.find(pt);
      if (tbti != Type::type_btypes.end() && tbti->second.is_placeholder)
        {
          pt->finish_backend(gogo, tbti->second.btype);
          tbti->second.is_placeholder = false;
        }
    }
}

// Class Nil_type.

// Get the backend representation of a nil type.  FIXME: Is this ever
// actually called?

Btype*
Nil_type::do_get_backend(Gogo* gogo)
{
  return gogo->backend()->pointer_type(gogo->backend()->void_type());
}

// Make the nil type.

Type*
Type::make_nil_type()
{
  static Nil_type singleton_nil_type;
  return &singleton_nil_type;
}

// The type of a function call which returns multiple values.  This is
// really a struct, but we don't want to confuse a function call which
// returns a struct with a function call which returns multiple
// values.

class Call_multiple_result_type : public Type
{
 public:
  Call_multiple_result_type(Call_expression* call)
    : Type(TYPE_CALL_MULTIPLE_RESULT),
      call_(call)
  { }

 protected:
  bool
  do_has_pointer() const
  { return false; }

  bool
  do_compare_is_identity(Gogo*)
  { return false; }

  Btype*
  do_get_backend(Gogo* gogo)
  {
    go_assert(saw_errors());
    return gogo->backend()->error_type();
  }

  Expression*
  do_type_descriptor(Gogo*, Named_type*)
  {
    go_assert(saw_errors());
    return Expression::make_error(Linemap::unknown_location());
  }

  void
  do_reflection(Gogo*, std::string*) const
  { go_assert(saw_errors()); }

  void
  do_mangled_name(Gogo*, std::string*) const
  { go_assert(saw_errors()); }

 private:
  // The expression being called.
  Call_expression* call_;
};

// Make a call result type.

Type*
Type::make_call_multiple_result_type(Call_expression* call)
{
  return new Call_multiple_result_type(call);
}

// Class Struct_field.

// Get the name of a field.

const std::string&
Struct_field::field_name() const
{
  const std::string& name(this->typed_identifier_.name());
  if (!name.empty())
    return name;
  else
    {
      // This is called during parsing, before anything is lowered, so
      // we have to be pretty careful to avoid dereferencing an
      // unknown type name.
      Type* t = this->typed_identifier_.type();
      Type* dt = t;
      if (t->classification() == Type::TYPE_POINTER)
	{
	  // Very ugly.
	  Pointer_type* ptype = static_cast<Pointer_type*>(t);
	  dt = ptype->points_to();
	}
      if (dt->forward_declaration_type() != NULL)
	return dt->forward_declaration_type()->name();
      else if (dt->named_type() != NULL)
	{
	  // Note that this can be an alias name.
	  return dt->named_type()->name();
	}
      else if (t->is_error_type() || dt->is_error_type())
	{
	  static const std::string error_string = "*error*";
	  return error_string;
	}
      else
	{
	  // Avoid crashing in the erroneous case where T is named but
	  // DT is not.
	  go_assert(t != dt);
	  if (t->forward_declaration_type() != NULL)
	    return t->forward_declaration_type()->name();
	  else if (t->named_type() != NULL)
	    return t->named_type()->name();
	  else
	    go_unreachable();
	}
    }
}

// Return whether this field is named NAME.

bool
Struct_field::is_field_name(const std::string& name) const
{
  const std::string& me(this->typed_identifier_.name());
  if (!me.empty())
    return me == name;
  else
    {
      Type* t = this->typed_identifier_.type();
      if (t->points_to() != NULL)
	t = t->points_to();
      Named_type* nt = t->named_type();
      if (nt != NULL && nt->name() == name)
	return true;

      // This is a horrible hack caused by the fact that we don't pack
      // the names of builtin types.  FIXME.
      if (!this->is_imported_
	  && nt != NULL
	  && nt->is_builtin()
	  && nt->name() == Gogo::unpack_hidden_name(name))
	return true;

      return false;
    }
}

// Return whether this field is an unexported field named NAME.

bool
Struct_field::is_unexported_field_name(Gogo* gogo,
				       const std::string& name) const
{
  const std::string& field_name(this->field_name());
  if (Gogo::is_hidden_name(field_name)
      && name == Gogo::unpack_hidden_name(field_name)
      && gogo->pack_hidden_name(name, false) != field_name)
    return true;

  // Check for the name of a builtin type.  This is like the test in
  // is_field_name, only there we return false if this->is_imported_,
  // and here we return true.
  if (this->is_imported_ && this->is_anonymous())
    {
      Type* t = this->typed_identifier_.type();
      if (t->points_to() != NULL)
	t = t->points_to();
      Named_type* nt = t->named_type();
      if (nt != NULL
	  && nt->is_builtin()
	  && nt->name() == Gogo::unpack_hidden_name(name))
	return true;
    }

  return false;
}

// Return whether this field is an embedded built-in type.

bool
Struct_field::is_embedded_builtin(Gogo* gogo) const
{
  const std::string& name(this->field_name());
  // We know that a field is an embedded type if it is anonymous.
  // We can decide if it is a built-in type by checking to see if it is
  // registered globally under the field's name.
  // This allows us to distinguish between embedded built-in types and
  // embedded types that are aliases to built-in types.
  return (this->is_anonymous()
          && !Gogo::is_hidden_name(name)
          && gogo->lookup_global(name.c_str()) != NULL);
}

// Class Struct_type.

// A hash table used to find identical unnamed structs so that they
// share method tables.

Struct_type::Identical_structs Struct_type::identical_structs;

// A hash table used to merge method sets for identical unnamed
// structs.

Struct_type::Struct_method_tables Struct_type::struct_method_tables;

// Traversal.

int
Struct_type::do_traverse(Traverse* traverse)
{
  Struct_field_list* fields = this->fields_;
  if (fields != NULL)
    {
      for (Struct_field_list::iterator p = fields->begin();
	   p != fields->end();
	   ++p)
	{
	  if (Type::traverse(p->type(), traverse) == TRAVERSE_EXIT)
	    return TRAVERSE_EXIT;
	}
    }
  return TRAVERSE_CONTINUE;
}

// Verify that the struct type is complete and valid.

bool
Struct_type::do_verify()
{
  Struct_field_list* fields = this->fields_;
  if (fields == NULL)
    return true;
  for (Struct_field_list::iterator p = fields->begin();
       p != fields->end();
       ++p)
    {
      Type* t = p->type();
      if (p->is_anonymous())
	{
	  if ((t->named_type() != NULL && t->points_to() != NULL)
              || (t->named_type() == NULL && t->points_to() != NULL
                  && t->points_to()->points_to() != NULL))
	    {
	      go_error_at(p->location(), "embedded type may not be a pointer");
	      p->set_type(Type::make_error_type());
	    }
	  else if (t->points_to() != NULL
		   && t->points_to()->interface_type() != NULL)
	    {
	      go_error_at(p->location(),
		       "embedded type may not be pointer to interface");
	      p->set_type(Type::make_error_type());
	    }
	}
    }
  return true;
}

// Whether this contains a pointer.

bool
Struct_type::do_has_pointer() const
{
  const Struct_field_list* fields = this->fields();
  if (fields == NULL)
    return false;
  for (Struct_field_list::const_iterator p = fields->begin();
       p != fields->end();
       ++p)
    {
      if (p->type()->has_pointer())
	return true;
    }
  return false;
}

// Whether this type is identical to T.

bool
Struct_type::is_identical(const Struct_type* t, int flags) const
{
  if (this->is_struct_incomparable_ != t->is_struct_incomparable_)
    return false;
  const Struct_field_list* fields1 = this->fields();
  const Struct_field_list* fields2 = t->fields();
  if (fields1 == NULL || fields2 == NULL)
    return fields1 == fields2;
  Struct_field_list::const_iterator pf2 = fields2->begin();
  for (Struct_field_list::const_iterator pf1 = fields1->begin();
       pf1 != fields1->end();
       ++pf1, ++pf2)
    {
      if (pf2 == fields2->end())
	return false;
      if (pf1->field_name() != pf2->field_name())
	return false;
      if (pf1->is_anonymous() != pf2->is_anonymous()
	  || !Type::are_identical(pf1->type(), pf2->type(), flags, NULL))
	return false;
      if ((flags & Type::COMPARE_TAGS) != 0)
	{
	  if (!pf1->has_tag())
	    {
	      if (pf2->has_tag())
		return false;
	    }
	  else
	    {
	      if (!pf2->has_tag())
		return false;
	      if (pf1->tag() != pf2->tag())
		return false;
	    }
	}
    }
  if (pf2 != fields2->end())
    return false;
  return true;
}

// Whether comparisons of this struct type are simple identity
// comparisons.

bool
Struct_type::do_compare_is_identity(Gogo* gogo)
{
  const Struct_field_list* fields = this->fields_;
  if (fields == NULL)
    return true;
  int64_t offset = 0;
  for (Struct_field_list::const_iterator pf = fields->begin();
       pf != fields->end();
       ++pf)
    {
      if (Gogo::is_sink_name(pf->field_name()))
	return false;

      if (!pf->type()->compare_is_identity(gogo))
	return false;

      int64_t field_align;
      if (!pf->type()->backend_type_align(gogo, &field_align))
	return false;
      if ((offset & (field_align - 1)) != 0)
	{
	  // This struct has padding.  We don't guarantee that that
	  // padding is zero-initialized for a stack variable, so we
	  // can't use memcmp to compare struct values.
	  return false;
	}

      int64_t field_size;
      if (!pf->type()->backend_type_size(gogo, &field_size))
	return false;
      offset += field_size;
    }

  int64_t struct_size;
  if (!this->backend_type_size(gogo, &struct_size))
    return false;
  if (offset != struct_size)
    {
      // Trailing padding may not be zero when on the stack.
      return false;
    }

  return true;
}

// Return whether this struct type is reflexive--whether a value of
// this type is always equal to itself.

bool
Struct_type::do_is_reflexive()
{
  const Struct_field_list* fields = this->fields_;
  if (fields == NULL)
    return true;
  for (Struct_field_list::const_iterator pf = fields->begin();
       pf != fields->end();
       ++pf)
    {
      if (!pf->type()->is_reflexive())
	return false;
    }
  return true;
}

// Return whether this struct type needs a key update when used as a
// map key.

bool
Struct_type::do_needs_key_update()
{
  const Struct_field_list* fields = this->fields_;
  if (fields == NULL)
    return false;
  for (Struct_field_list::const_iterator pf = fields->begin();
       pf != fields->end();
       ++pf)
    {
      if (pf->type()->needs_key_update())
	return true;
    }
  return false;
}

// Return whether this struct type is permitted to be in the heap.

bool
Struct_type::do_in_heap()
{
  const Struct_field_list* fields = this->fields_;
  if (fields == NULL)
    return true;
  for (Struct_field_list::const_iterator pf = fields->begin();
       pf != fields->end();
       ++pf)
    {
      if (!pf->type()->in_heap())
	return false;
    }
  return true;
}

// Build identity and hash functions for this struct.

// Hash code.

unsigned int
Struct_type::do_hash_for_method(Gogo* gogo, int flags) const
{
  unsigned int ret = 0;
  if (this->fields() != NULL)
    {
      for (Struct_field_list::const_iterator pf = this->fields()->begin();
	   pf != this->fields()->end();
	   ++pf)
	ret = (ret << 1) + pf->type()->hash_for_method(gogo, flags);
    }
  ret <<= 2;
  if (this->is_struct_incomparable_)
    ret <<= 1;
  return ret;
}

// Find the local field NAME.

const Struct_field*
Struct_type::find_local_field(const std::string& name,
			      unsigned int *pindex) const
{
  const Struct_field_list* fields = this->fields_;
  if (fields == NULL)
    return NULL;
  unsigned int i = 0;
  for (Struct_field_list::const_iterator pf = fields->begin();
       pf != fields->end();
       ++pf, ++i)
    {
      if (pf->is_field_name(name))
	{
	  if (pindex != NULL)
	    *pindex = i;
	  return &*pf;
	}
    }
  return NULL;
}

// Return an expression for field NAME in STRUCT_EXPR, or NULL.

Field_reference_expression*
Struct_type::field_reference(Expression* struct_expr, const std::string& name,
			     Location location) const
{
  unsigned int depth;
  return this->field_reference_depth(struct_expr, name, location, NULL,
				     &depth);
}

// Return an expression for a field, along with the depth at which it
// was found.

Field_reference_expression*
Struct_type::field_reference_depth(Expression* struct_expr,
				   const std::string& name,
				   Location location,
				   Saw_named_type* saw,
				   unsigned int* depth) const
{
  const Struct_field_list* fields = this->fields_;
  if (fields == NULL)
    return NULL;

  // Look for a field with this name.
  unsigned int i = 0;
  for (Struct_field_list::const_iterator pf = fields->begin();
       pf != fields->end();
       ++pf, ++i)
    {
      if (pf->is_field_name(name))
	{
	  *depth = 0;
	  return Expression::make_field_reference(struct_expr, i, location);
	}
    }

  // Look for an anonymous field which contains a field with this
  // name.
  unsigned int found_depth = 0;
  Field_reference_expression* ret = NULL;
  i = 0;
  for (Struct_field_list::const_iterator pf = fields->begin();
       pf != fields->end();
       ++pf, ++i)
    {
      if (!pf->is_anonymous())
	continue;

      Struct_type* st = pf->type()->deref()->struct_type();
      if (st == NULL)
	continue;

      Saw_named_type* hold_saw = saw;
      Saw_named_type saw_here;
      Named_type* nt = pf->type()->named_type();
      if (nt == NULL)
	nt = pf->type()->deref()->named_type();
      if (nt != NULL)
	{
	  Saw_named_type* q;
	  for (q = saw; q != NULL; q = q->next)
	    {
	      if (q->nt == nt)
		{
		  // If this is an error, it will be reported
		  // elsewhere.
		  break;
		}
	    }
	  if (q != NULL)
	    continue;
	  saw_here.next = saw;
	  saw_here.nt = nt;
	  saw = &saw_here;
	}

      // Look for a reference using a NULL struct expression.  If we
      // find one, fill in the struct expression with a reference to
      // this field.
      unsigned int subdepth;
      Field_reference_expression* sub = st->field_reference_depth(NULL, name,
								  location,
								  saw,
								  &subdepth);

      saw = hold_saw;

      if (sub == NULL)
	continue;

      if (ret == NULL || subdepth < found_depth)
	{
	  if (ret != NULL)
	    delete ret;
	  ret = sub;
	  found_depth = subdepth;
	  Expression* here = Expression::make_field_reference(struct_expr, i,
							      location);
	  if (pf->type()->points_to() != NULL)
            here = Expression::make_dereference(here,
                                                Expression::NIL_CHECK_DEFAULT,
                                                location);
	  while (sub->expr() != NULL)
	    {
	      sub = sub->expr()->deref()->field_reference_expression();
	      go_assert(sub != NULL);
	    }
	  sub->set_struct_expression(here);
          sub->set_implicit(true);
	}
      else if (subdepth > found_depth)
	delete sub;
      else
	{
	  // We do not handle ambiguity here--it should be handled by
	  // Type::bind_field_or_method.
	  delete sub;
	  found_depth = 0;
	  ret = NULL;
	}
    }

  if (ret != NULL)
    *depth = found_depth + 1;

  return ret;
}

// Return the total number of fields, including embedded fields.

unsigned int
Struct_type::total_field_count() const
{
  if (this->fields_ == NULL)
    return 0;
  unsigned int ret = 0;
  for (Struct_field_list::const_iterator pf = this->fields_->begin();
       pf != this->fields_->end();
       ++pf)
    {
      if (!pf->is_anonymous() || pf->type()->struct_type() == NULL)
	++ret;
      else
	ret += pf->type()->struct_type()->total_field_count();
    }
  return ret;
}

// Return whether NAME is an unexported field, for better error reporting.

bool
Struct_type::is_unexported_local_field(Gogo* gogo,
				       const std::string& name) const
{
  const Struct_field_list* fields = this->fields_;
  if (fields != NULL)
    {
      for (Struct_field_list::const_iterator pf = fields->begin();
	   pf != fields->end();
	   ++pf)
	if (pf->is_unexported_field_name(gogo, name))
	  return true;
    }
  return false;
}

// Finalize the methods of an unnamed struct.

void
Struct_type::finalize_methods(Gogo* gogo)
{
  if (this->all_methods_ != NULL)
    return;

  // It is possible to have multiple identical structs that have
  // methods.  We want them to share method tables.  Otherwise we will
  // emit identical methods more than once, which is bad since they
  // will even have the same names.
  std::pair<Identical_structs::iterator, bool> ins =
    Struct_type::identical_structs.insert(std::make_pair(this, this));
  if (!ins.second)
    {
      // An identical struct was already entered into the hash table.
      // Note that finalize_methods is, fortunately, not recursive.
      this->all_methods_ = ins.first->second->all_methods_;
      return;
    }

  Type::finalize_methods(gogo, this, this->location_, &this->all_methods_);
}

// Return the method NAME, or NULL if there isn't one or if it is
// ambiguous.  Set *IS_AMBIGUOUS if the method exists but is
// ambiguous.

Method*
Struct_type::method_function(const std::string& name, bool* is_ambiguous) const
{
  return Type::method_function(this->all_methods_, name, is_ambiguous);
}

// Return a pointer to the interface method table for this type for
// the interface INTERFACE.  IS_POINTER is true if this is for a
// pointer to THIS.

Expression*
Struct_type::interface_method_table(Interface_type* interface,
				    bool is_pointer)
{
  std::pair<Struct_type*, Struct_type::Struct_method_table_pair*>
    val(this, NULL);
  std::pair<Struct_type::Struct_method_tables::iterator, bool> ins =
    Struct_type::struct_method_tables.insert(val);

  Struct_method_table_pair* smtp;
  if (!ins.second)
    smtp = ins.first->second;
  else
    {
      smtp = new Struct_method_table_pair();
      smtp->first = NULL;
      smtp->second = NULL;
      ins.first->second = smtp;
    }

  return Type::interface_method_table(this, interface, is_pointer,
				      &smtp->first, &smtp->second);
}

// Convert struct fields to the backend representation.  This is not
// declared in types.h so that types.h doesn't have to #include
// backend.h.

static void
get_backend_struct_fields(Gogo* gogo, const Struct_field_list* fields,
			  bool use_placeholder,
			  std::vector<Backend::Btyped_identifier>* bfields)
{
  bfields->resize(fields->size());
  size_t i = 0;
  for (Struct_field_list::const_iterator p = fields->begin();
       p != fields->end();
       ++p, ++i)
    {
      (*bfields)[i].name = Gogo::unpack_hidden_name(p->field_name());
      (*bfields)[i].btype = (use_placeholder
			     ? p->type()->get_backend_placeholder(gogo)
			     : p->type()->get_backend(gogo));
      (*bfields)[i].location = p->location();
    }
  go_assert(i == fields->size());
}

// Get the backend representation for a struct type.

Btype*
Struct_type::do_get_backend(Gogo* gogo)
{
  std::vector<Backend::Btyped_identifier> bfields;
  get_backend_struct_fields(gogo, this->fields_, false, &bfields);
  return gogo->backend()->struct_type(bfields);
}

// Finish the backend representation of the fields of a struct.

void
Struct_type::finish_backend_fields(Gogo* gogo)
{
  const Struct_field_list* fields = this->fields_;
  if (fields != NULL)
    {
      for (Struct_field_list::const_iterator p = fields->begin();
	   p != fields->end();
	   ++p)
	p->type()->get_backend(gogo);
    }
}

// The type of a struct type descriptor.

Type*
Struct_type::make_struct_type_descriptor_type()
{
  static Type* ret;
  if (ret == NULL)
    {
      Type* tdt = Type::make_type_descriptor_type();
      Type* ptdt = Type::make_type_descriptor_ptr_type();

      Type* uintptr_type = Type::lookup_integer_type("uintptr");
      Type* string_type = Type::lookup_string_type();
      Type* pointer_string_type = Type::make_pointer_type(string_type);

      Struct_type* sf =
	Type::make_builtin_struct_type(5,
				       "name", pointer_string_type,
				       "pkgPath", pointer_string_type,
				       "typ", ptdt,
				       "tag", pointer_string_type,
				       "offsetAnon", uintptr_type);
      Type* nsf = Type::make_builtin_named_type("structField", sf);

      Type* slice_type = Type::make_array_type(nsf, NULL);

      Struct_type* s = Type::make_builtin_struct_type(2,
						      "", tdt,
						      "fields", slice_type);

      ret = Type::make_builtin_named_type("StructType", s);
    }

  return ret;
}

// Build a type descriptor for a struct type.

Expression*
Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  Location bloc = Linemap::predeclared_location();

  Type* stdt = Struct_type::make_struct_type_descriptor_type();

  const Struct_field_list* fields = stdt->struct_type()->fields();

  Expression_list* vals = new Expression_list();
  vals->reserve(2);

  const Methods* methods = this->methods();
  // A named struct should not have methods--the methods should attach
  // to the named type.
  go_assert(methods == NULL || name == NULL);

  Struct_field_list::const_iterator ps = fields->begin();
  go_assert(ps->is_field_name("_type"));
  vals->push_back(this->type_descriptor_constructor(gogo,
						    RUNTIME_TYPE_KIND_STRUCT,
						    name, methods, true));

  ++ps;
  go_assert(ps->is_field_name("fields"));

  Expression_list* elements = new Expression_list();
  elements->reserve(this->fields_->size());
  Type* element_type = ps->type()->array_type()->element_type();
  for (Struct_field_list::const_iterator pf = this->fields_->begin();
       pf != this->fields_->end();
       ++pf)
    {
      const Struct_field_list* f = element_type->struct_type()->fields();

      Expression_list* fvals = new Expression_list();
      fvals->reserve(5);

      Struct_field_list::const_iterator q = f->begin();
      go_assert(q->is_field_name("name"));
      std::string n = Gogo::unpack_hidden_name(pf->field_name());
      Expression* s = Expression::make_string(n, bloc);
      fvals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));

      ++q;
      go_assert(q->is_field_name("pkgPath"));
      bool is_embedded_builtin = pf->is_embedded_builtin(gogo);
      if (!Gogo::is_hidden_name(pf->field_name()) && !is_embedded_builtin)
        fvals->push_back(Expression::make_nil(bloc));
      else
	{
	  std::string n;
          if (is_embedded_builtin)
            n = gogo->package_name();
          else
            n = Gogo::hidden_name_pkgpath(pf->field_name());
	  Expression* s = Expression::make_string(n, bloc);
	  fvals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
	}

      ++q;
      go_assert(q->is_field_name("typ"));
      fvals->push_back(Expression::make_type_descriptor(pf->type(), bloc));

      ++q;
      go_assert(q->is_field_name("tag"));
      if (!pf->has_tag())
	fvals->push_back(Expression::make_nil(bloc));
      else
	{
	  Expression* s = Expression::make_string(pf->tag(), bloc);
	  fvals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
	}

      ++q;
      go_assert(q->is_field_name("offsetAnon"));
      Type* uintptr_type = Type::lookup_integer_type("uintptr");
      Expression* o = Expression::make_struct_field_offset(this, &*pf);
      Expression* one = Expression::make_integer_ul(1, uintptr_type, bloc);
      o = Expression::make_binary(OPERATOR_LSHIFT, o, one, bloc);
      int av = pf->is_anonymous() ? 1 : 0;
      Expression* anon = Expression::make_integer_ul(av, uintptr_type, bloc);
      o = Expression::make_binary(OPERATOR_OR, o, anon, bloc);
      fvals->push_back(o);

      Expression* v = Expression::make_struct_composite_literal(element_type,
								fvals, bloc);
      elements->push_back(v);
    }

  vals->push_back(Expression::make_slice_composite_literal(ps->type(),
							   elements, bloc));

  return Expression::make_struct_composite_literal(stdt, vals, bloc);
}

// Write the hash function for a struct which can not use the identity
// function.

void
Struct_type::write_hash_function(Gogo* gogo, Named_type*,
				 Function_type* hash_fntype,
				 Function_type* equal_fntype)
{
  Location bloc = Linemap::predeclared_location();

  // The pointer to the struct that we are going to hash.  This is an
  // argument to the hash function we are implementing here.
  Named_object* key_arg = gogo->lookup("key", NULL);
  go_assert(key_arg != NULL);
  Type* key_arg_type = key_arg->var_value()->type();

  // The seed argument to the hash function.
  Named_object* seed_arg = gogo->lookup("seed", NULL);
  go_assert(seed_arg != NULL);

  Type* uintptr_type = Type::lookup_integer_type("uintptr");

  // Make a temporary to hold the return value, initialized to the seed.
  Expression* ref = Expression::make_var_reference(seed_arg, bloc);
  Temporary_statement* retval = Statement::make_temporary(uintptr_type, ref,
							  bloc);
  gogo->add_statement(retval);

  // Make a temporary to hold the key as a uintptr.
  ref = Expression::make_var_reference(key_arg, bloc);
  ref = Expression::make_cast(uintptr_type, ref, bloc);
  Temporary_statement* key = Statement::make_temporary(uintptr_type, ref,
						       bloc);
  gogo->add_statement(key);

  // Loop over the struct fields.
  const Struct_field_list* fields = this->fields_;
  for (Struct_field_list::const_iterator pf = fields->begin();
       pf != fields->end();
       ++pf)
    {
      if (Gogo::is_sink_name(pf->field_name()))
	continue;

      // Get a pointer to the value of this field.
      Expression* offset = Expression::make_struct_field_offset(this, &*pf);
      ref = Expression::make_temporary_reference(key, bloc);
      Expression* subkey = Expression::make_binary(OPERATOR_PLUS, ref, offset,
						   bloc);
      subkey = Expression::make_cast(key_arg_type, subkey, bloc);

      // Get the hash function to use for the type of this field.
      Named_object* hash_fn;
      Named_object* equal_fn;
      pf->type()->type_functions(gogo, pf->type()->named_type(), hash_fntype,
				 equal_fntype, &hash_fn, &equal_fn);

      // Call the hash function for the field, passing retval as the seed.
      ref = Expression::make_temporary_reference(retval, bloc);
      Expression_list* args = new Expression_list();
      args->push_back(subkey);
      args->push_back(ref);
      Expression* func = Expression::make_func_reference(hash_fn, NULL, bloc);
      Expression* call = Expression::make_call(func, args, false, bloc);

      // Set retval to the result.
      Temporary_reference_expression* tref =
	Expression::make_temporary_reference(retval, bloc);
      tref->set_is_lvalue();
      Statement* s = Statement::make_assignment(tref, call, bloc);
      gogo->add_statement(s);
    }

  // Return retval to the caller of the hash function.
  Expression_list* vals = new Expression_list();
  ref = Expression::make_temporary_reference(retval, bloc);
  vals->push_back(ref);
  Statement* s = Statement::make_return_statement(vals, bloc);
  gogo->add_statement(s);
}

// Write the equality function for a struct which can not use the
// identity function.

void
Struct_type::write_equal_function(Gogo* gogo, Named_type* name)
{
  Location bloc = Linemap::predeclared_location();

  // The pointers to the structs we are going to compare.
  Named_object* key1_arg = gogo->lookup("key1", NULL);
  Named_object* key2_arg = gogo->lookup("key2", NULL);
  go_assert(key1_arg != NULL && key2_arg != NULL);

  // Build temporaries with the right types.
  Type* pt = Type::make_pointer_type(name != NULL
				     ? static_cast<Type*>(name)
				     : static_cast<Type*>(this));

  Expression* ref = Expression::make_var_reference(key1_arg, bloc);
  ref = Expression::make_unsafe_cast(pt, ref, bloc);
  Temporary_statement* p1 = Statement::make_temporary(pt, ref, bloc);
  gogo->add_statement(p1);

  ref = Expression::make_var_reference(key2_arg, bloc);
  ref = Expression::make_unsafe_cast(pt, ref, bloc);
  Temporary_statement* p2 = Statement::make_temporary(pt, ref, bloc);
  gogo->add_statement(p2);

  const Struct_field_list* fields = this->fields_;
  unsigned int field_index = 0;
  for (Struct_field_list::const_iterator pf = fields->begin();
       pf != fields->end();
       ++pf, ++field_index)
    {
      if (Gogo::is_sink_name(pf->field_name()))
	continue;

      // Compare one field in both P1 and P2.
      Expression* f1 = Expression::make_temporary_reference(p1, bloc);
      f1 = Expression::make_dereference(f1, Expression::NIL_CHECK_DEFAULT,
                                        bloc);
      f1 = Expression::make_field_reference(f1, field_index, bloc);

      Expression* f2 = Expression::make_temporary_reference(p2, bloc);
      f2 = Expression::make_dereference(f2, Expression::NIL_CHECK_DEFAULT,
                                        bloc);
      f2 = Expression::make_field_reference(f2, field_index, bloc);

      Expression* cond = Expression::make_binary(OPERATOR_NOTEQ, f1, f2, bloc);

      // If the values are not equal, return false.
      gogo->start_block(bloc);
      Expression_list* vals = new Expression_list();
      vals->push_back(Expression::make_boolean(false, bloc));
      Statement* s = Statement::make_return_statement(vals, bloc);
      gogo->add_statement(s);
      Block* then_block = gogo->finish_block(bloc);

      s = Statement::make_if_statement(cond, then_block, NULL, bloc);
      gogo->add_statement(s);
    }

  // All the fields are equal, so return true.
  Expression_list* vals = new Expression_list();
  vals->push_back(Expression::make_boolean(true, bloc));
  Statement* s = Statement::make_return_statement(vals, bloc);
  gogo->add_statement(s);
}

// Reflection string.

void
Struct_type::do_reflection(Gogo* gogo, std::string* ret) const
{
  ret->append("struct {");

  for (Struct_field_list::const_iterator p = this->fields_->begin();
       p != this->fields_->end();
       ++p)
    {
      if (p != this->fields_->begin())
	ret->push_back(';');
      ret->push_back(' ');
      if (!p->is_anonymous())
	{
	  ret->append(Gogo::unpack_hidden_name(p->field_name()));
	  ret->push_back(' ');
	}
      if (p->is_anonymous()
	  && p->type()->named_type() != NULL
	  && p->type()->named_type()->is_alias())
	p->type()->named_type()->append_reflection_type_name(gogo, true, ret);
      else
	this->append_reflection(p->type(), gogo, ret);

      if (p->has_tag())
	{
	  const std::string& tag(p->tag());
	  ret->append(" \"");
	  for (std::string::const_iterator p = tag.begin();
	       p != tag.end();
	       ++p)
	    {
	      if (*p == '\0')
		ret->append("\\x00");
	      else if (*p == '\n')
		ret->append("\\n");
	      else if (*p == '\t')
		ret->append("\\t");
	      else if (*p == '"')
		ret->append("\\\"");
	      else if (*p == '\\')
		ret->append("\\\\");
	      else
		ret->push_back(*p);
	    }
	  ret->push_back('"');
	}
    }

  if (!this->fields_->empty())
    ret->push_back(' ');

  ret->push_back('}');
}

// If the offset of field INDEX in the backend implementation can be
// determined, set *POFFSET to the offset in bytes and return true.
// Otherwise, return false.

bool
Struct_type::backend_field_offset(Gogo* gogo, unsigned int index,
				  int64_t* poffset)
{
  if (!this->is_backend_type_size_known(gogo))
    return false;
  Btype* bt = this->get_backend_placeholder(gogo);
  *poffset = gogo->backend()->type_field_offset(bt, index);
  return true;
}

// Export.

void
Struct_type::do_export(Export* exp) const
{
  exp->write_c_string("struct { ");
  const Struct_field_list* fields = this->fields_;
  go_assert(fields != NULL);
  for (Struct_field_list::const_iterator p = fields->begin();
       p != fields->end();
       ++p)
    {
      if (p->is_anonymous())
	exp->write_string("? ");
      else
	{
	  exp->write_string(p->field_name());
	  exp->write_c_string(" ");
	}
      exp->write_type(p->type());

      if (p->has_tag())
	{
	  exp->write_c_string(" ");
	  Expression* expr =
            Expression::make_string(p->tag(), Linemap::predeclared_location());
	  expr->export_expression(exp);
	  delete expr;
	}

      exp->write_c_string("; ");
    }
  exp->write_c_string("}");
}

// Import.

Struct_type*
Struct_type::do_import(Import* imp)
{
  imp->require_c_string("struct { ");
  Struct_field_list* fields = new Struct_field_list;
  if (imp->peek_char() != '}')
    {
      while (true)
	{
	  std::string name;
	  if (imp->match_c_string("? "))
	    imp->advance(2);
	  else
	    {
	      name = imp->read_identifier();
	      imp->require_c_string(" ");
	    }
	  Type* ftype = imp->read_type();

	  Struct_field sf(Typed_identifier(name, ftype, imp->location()));
	  sf.set_is_imported();

	  if (imp->peek_char() == ' ')
	    {
	      imp->advance(1);
	      Expression* expr = Expression::import_expression(imp);
	      String_expression* sexpr = expr->string_expression();
	      go_assert(sexpr != NULL);
	      sf.set_tag(sexpr->val());
	      delete sexpr;
	    }

	  imp->require_c_string("; ");
	  fields->push_back(sf);
	  if (imp->peek_char() == '}')
	    break;
	}
    }
  imp->require_c_string("}");

  return Type::make_struct_type(fields, imp->location());
}

// Whether we can write this struct type to a C header file.
// We can't if any of the fields are structs defined in a different package.

bool
Struct_type::can_write_to_c_header(
    std::vector<const Named_object*>* requires,
    std::vector<const Named_object*>* declare) const
{
  const Struct_field_list* fields = this->fields_;
  if (fields == NULL || fields->empty())
    return false;
  int sinks = 0;
  for (Struct_field_list::const_iterator p = fields->begin();
       p != fields->end();
       ++p)
    {
      if (p->is_anonymous())
	return false;
      if (!this->can_write_type_to_c_header(p->type(), requires, declare))
	return false;
      if (Gogo::message_name(p->field_name()) == "_")
	sinks++;
    }
  if (sinks > 1)
    return false;
  return true;
}

// Whether we can write the type T to a C header file.

bool
Struct_type::can_write_type_to_c_header(
    const Type* t,
    std::vector<const Named_object*>* requires,
    std::vector<const Named_object*>* declare) const
{
  t = t->forwarded();
  switch (t->classification())
    {
    case TYPE_ERROR:
    case TYPE_FORWARD:
      return false;

    case TYPE_VOID:
    case TYPE_BOOLEAN:
    case TYPE_INTEGER:
    case TYPE_FLOAT:
    case TYPE_COMPLEX:
    case TYPE_STRING:
    case TYPE_FUNCTION:
    case TYPE_MAP:
    case TYPE_CHANNEL:
    case TYPE_INTERFACE:
      return true;

    case TYPE_POINTER:
      // Don't try to handle a pointer to an array.
      if (t->points_to()->array_type() != NULL
	  && !t->points_to()->is_slice_type())
	return false;

      if (t->points_to()->named_type() != NULL
	  && t->points_to()->struct_type() != NULL)
	declare->push_back(t->points_to()->named_type()->named_object());
      return true;

    case TYPE_STRUCT:
      return t->struct_type()->can_write_to_c_header(requires, declare);

    case TYPE_ARRAY:
      if (t->is_slice_type())
	return true;
      return this->can_write_type_to_c_header(t->array_type()->element_type(),
					      requires, declare);

    case TYPE_NAMED:
      {
	const Named_object* no = t->named_type()->named_object();
	if (no->package() != NULL)
	  {
	    if (t->is_unsafe_pointer_type())
	      return true;
	    return false;
	  }
	if (t->struct_type() != NULL)
	  {
	    requires->push_back(no);
	    return t->struct_type()->can_write_to_c_header(requires, declare);
	  }
	return this->can_write_type_to_c_header(t->base(), requires, declare);
      }

    case TYPE_CALL_MULTIPLE_RESULT:
    case TYPE_NIL:
    case TYPE_SINK:
    default:
      go_unreachable();
    }
}

// Write this struct to a C header file.

void
Struct_type::write_to_c_header(std::ostream& os) const
{
  const Struct_field_list* fields = this->fields_;
  for (Struct_field_list::const_iterator p = fields->begin();
       p != fields->end();
       ++p)
    {
      os << '\t';
      this->write_field_to_c_header(os, p->field_name(), p->type());
      os << ';' << std::endl;
    }
}

// Write the type of a struct field to a C header file.

void
Struct_type::write_field_to_c_header(std::ostream& os, const std::string& name,
				     const Type *t) const
{
  bool print_name = true;
  t = t->forwarded();
  switch (t->classification())
    {
    case TYPE_VOID:
      os << "void";
      break;

    case TYPE_BOOLEAN:
      os << "_Bool";
      break;

    case TYPE_INTEGER:
      {
	const Integer_type* it = t->integer_type();
	if (it->is_unsigned())
	  os << 'u';
	os << "int" << it->bits() << "_t";
      }
      break;

    case TYPE_FLOAT:
      switch (t->float_type()->bits())
	{
	case 32:
	  os << "float";
	  break;
	case 64:
	  os << "double";
	  break;
	default:
	  go_unreachable();
	}
      break;

    case TYPE_COMPLEX:
      switch (t->complex_type()->bits())
	{
	case 64:
	  os << "float _Complex";
	  break;
	case 128:
	  os << "double _Complex";
	  break;
	default:
	  go_unreachable();
	}
      break;

    case TYPE_STRING:
      os << "String";
      break;

    case TYPE_FUNCTION:
      os << "FuncVal*";
      break;

    case TYPE_POINTER:
      {
	std::vector<const Named_object*> requires;
	std::vector<const Named_object*> declare;
	if (!this->can_write_type_to_c_header(t->points_to(), &requires,
					      &declare))
	  os << "void*";
	else
	  {
	    this->write_field_to_c_header(os, "", t->points_to());
	    os << '*';
	  }
      }
      break;

    case TYPE_MAP:
      os << "Map*";
      break;

    case TYPE_CHANNEL:
      os << "Chan*";
      break;

    case TYPE_INTERFACE:
      if (t->interface_type()->is_empty())
	os << "Eface";
      else
	os << "Iface";
      break;

    case TYPE_STRUCT:
      os << "struct {" << std::endl;
      t->struct_type()->write_to_c_header(os);
      os << "\t}";
      break;

    case TYPE_ARRAY:
      if (t->is_slice_type())
	os << "Slice";
      else
	{
	  const Type *ele = t;
	  std::vector<const Type*> array_types;
	  while (ele->array_type() != NULL && !ele->is_slice_type())
	    {
	      array_types.push_back(ele);
	      ele = ele->array_type()->element_type();
	    }
	  this->write_field_to_c_header(os, "", ele);
	  os << ' ' << Gogo::message_name(name);
	  print_name = false;
	  while (!array_types.empty())
	    {
	      ele = array_types.back();
	      array_types.pop_back();
	      os << '[';
	      Numeric_constant nc;
	      if (!ele->array_type()->length()->numeric_constant_value(&nc))
		go_unreachable();
	      mpz_t val;
	      if (!nc.to_int(&val))
		go_unreachable();
	      char* s = mpz_get_str(NULL, 10, val);
	      os << s;
	      free(s);
	      mpz_clear(val);
	      os << ']';
	    }
	}
      break;

    case TYPE_NAMED:
      {
	const Named_object* no = t->named_type()->named_object();
	if (t->struct_type() != NULL)
	  os << "struct " << no->message_name();
	else if (t->is_unsafe_pointer_type())
	  os << "void*";
	else if (t == Type::lookup_integer_type("uintptr"))
	  os << "uintptr_t";
	else
	  {
	    this->write_field_to_c_header(os, name, t->base());
	    print_name = false;
	  }
      }
      break;

    case TYPE_ERROR:
    case TYPE_FORWARD:
    case TYPE_CALL_MULTIPLE_RESULT:
    case TYPE_NIL:
    case TYPE_SINK:
    default:
      go_unreachable();
    }

  if (print_name && !name.empty())
    os << ' ' << Gogo::message_name(name);
}

// Make a struct type.

Struct_type*
Type::make_struct_type(Struct_field_list* fields,
		       Location location)
{
  return new Struct_type(fields, location);
}

// Class Array_type.

// Store the length of an array as an int64_t into *PLEN.  Return
// false if the length can not be determined.  This will assert if
// called for a slice.

bool
Array_type::int_length(int64_t* plen)
{
  go_assert(this->length_ != NULL);
  Numeric_constant nc;
  if (!this->length_->numeric_constant_value(&nc))
    return false;
  return nc.to_memory_size(plen);
}

// Whether two array types are identical.

bool
Array_type::is_identical(const Array_type* t, int flags) const
{
  if (!Type::are_identical(this->element_type(), t->element_type(),
			   flags, NULL))
    return false;

  if (this->is_array_incomparable_ != t->is_array_incomparable_)
    return false;

  Expression* l1 = this->length();
  Expression* l2 = t->length();

  // Slices of the same element type are identical.
  if (l1 == NULL && l2 == NULL)
    return true;

  // Arrays of the same element type are identical if they have the
  // same length.
  if (l1 != NULL && l2 != NULL)
    {
      if (l1 == l2)
	return true;

      // Try to determine the lengths.  If we can't, assume the arrays
      // are not identical.
      bool ret = false;
      Numeric_constant nc1, nc2;
      if (l1->numeric_constant_value(&nc1)
	  && l2->numeric_constant_value(&nc2))
	{
	  mpz_t v1;
	  if (nc1.to_int(&v1))
	    {
	      mpz_t v2;
	      if (nc2.to_int(&v2))
		{
		  ret = mpz_cmp(v1, v2) == 0;
		  mpz_clear(v2);
		}
	      mpz_clear(v1);
	    }
	}
      return ret;
    }

  // Otherwise the arrays are not identical.
  return false;
}

// Traversal.

int
Array_type::do_traverse(Traverse* traverse)
{
  if (Type::traverse(this->element_type_, traverse) == TRAVERSE_EXIT)
    return TRAVERSE_EXIT;
  if (this->length_ != NULL
      && Expression::traverse(&this->length_, traverse) == TRAVERSE_EXIT)
    return TRAVERSE_EXIT;
  return TRAVERSE_CONTINUE;
}

// Check that the length is valid.

bool
Array_type::verify_length()
{
  if (this->length_ == NULL)
    return true;

  Type_context context(Type::lookup_integer_type("int"), false);
  this->length_->determine_type(&context);

  if (!this->length_->is_constant())
    {
      go_error_at(this->length_->location(), "array bound is not constant");
      return false;
    }

  // For array types, the length expression can be an untyped constant
  // representable as an int, but we don't allow explicitly non-integer
  // values such as "float64(10)". See issues #13485 and #13486.
  if (this->length_->type()->integer_type() == NULL
      && !this->length_->type()->is_error_type())
    {
      go_error_at(this->length_->location(), "invalid array bound");
      return false;
    }

  Numeric_constant nc;
  if (!this->length_->numeric_constant_value(&nc))
    {
      if (this->length_->type()->integer_type() != NULL
	  || this->length_->type()->float_type() != NULL)
	go_error_at(this->length_->location(), "array bound is not constant");
      else
	go_error_at(this->length_->location(), "array bound is not numeric");
      return false;
    }

  Type* int_type = Type::lookup_integer_type("int");
  unsigned int tbits = int_type->integer_type()->bits();
  unsigned long val;
  switch (nc.to_unsigned_long(&val))
    {
    case Numeric_constant::NC_UL_VALID:
      if (sizeof(val) >= tbits / 8 && val >> (tbits - 1) != 0)
	{
	  go_error_at(this->length_->location(), "array bound overflows");
	  return false;
	}
      break;
    case Numeric_constant::NC_UL_NOTINT:
      go_error_at(this->length_->location(), "array bound truncated to integer");
      return false;
    case Numeric_constant::NC_UL_NEGATIVE:
      go_error_at(this->length_->location(), "negative array bound");
      return false;
    case Numeric_constant::NC_UL_BIG:
      {
	mpz_t val;
	if (!nc.to_int(&val))
	  go_unreachable();
	unsigned int bits = mpz_sizeinbase(val, 2);
	mpz_clear(val);
	if (bits >= tbits)
	  {
	    go_error_at(this->length_->location(), "array bound overflows");
	    return false;
	  }
      }
      break;
    default:
      go_unreachable();
    }

  return true;
}

// Verify the type.

bool
Array_type::do_verify()
{
  if (this->element_type()->is_error_type())
    return false;
  if (!this->verify_length())
    this->length_ = Expression::make_error(this->length_->location());
  return true;
}

// Whether the type contains pointers.  This is always true for a
// slice.  For an array it is true if the element type has pointers
// and the length is greater than zero.

bool
Array_type::do_has_pointer() const
{
  if (this->length_ == NULL)
    return true;
  if (!this->element_type_->has_pointer())
    return false;

  Numeric_constant nc;
  if (!this->length_->numeric_constant_value(&nc))
    {
      // Error reported elsewhere.
      return false;
    }

  unsigned long val;
  switch (nc.to_unsigned_long(&val))
    {
    case Numeric_constant::NC_UL_VALID:
      return val > 0;
    case Numeric_constant::NC_UL_BIG:
      return true;
    default:
      // Error reported elsewhere.
      return false;
    }
}

// Whether we can use memcmp to compare this array.

bool
Array_type::do_compare_is_identity(Gogo* gogo)
{
  if (this->length_ == NULL)
    return false;

  // Check for [...], which indicates that this is not a real type.
  if (this->length_->is_nil_expression())
    return false;

  if (!this->element_type_->compare_is_identity(gogo))
    return false;

  // If there is any padding, then we can't use memcmp.
  int64_t size;
  int64_t align;
  if (!this->element_type_->backend_type_size(gogo, &size)
      || !this->element_type_->backend_type_align(gogo, &align))
    return false;
  if ((size & (align - 1)) != 0)
    return false;

  return true;
}

// Array type hash code.

unsigned int
Array_type::do_hash_for_method(Gogo* gogo, int flags) const
{
  unsigned int ret;

  // There is no very convenient way to get a hash code for the
  // length.
  ret = this->element_type_->hash_for_method(gogo, flags) + 1;
  if (this->is_array_incomparable_)
    ret <<= 1;
  return ret;
}

// Write the hash function for an array which can not use the identify
// function.

void
Array_type::write_hash_function(Gogo* gogo, Named_type* name,
				Function_type* hash_fntype,
				Function_type* equal_fntype)
{
  Location bloc = Linemap::predeclared_location();

  // The pointer to the array that we are going to hash.  This is an
  // argument to the hash function we are implementing here.
  Named_object* key_arg = gogo->lookup("key", NULL);
  go_assert(key_arg != NULL);
  Type* key_arg_type = key_arg->var_value()->type();

  // The seed argument to the hash function.
  Named_object* seed_arg = gogo->lookup("seed", NULL);
  go_assert(seed_arg != NULL);

  Type* uintptr_type = Type::lookup_integer_type("uintptr");

  // Make a temporary to hold the return value, initialized to the seed.
  Expression* ref = Expression::make_var_reference(seed_arg, bloc);
  Temporary_statement* retval = Statement::make_temporary(uintptr_type, ref,
							  bloc);
  gogo->add_statement(retval);

  // Make a temporary to hold the key as a uintptr.
  ref = Expression::make_var_reference(key_arg, bloc);
  ref = Expression::make_cast(uintptr_type, ref, bloc);
  Temporary_statement* key = Statement::make_temporary(uintptr_type, ref,
						       bloc);
  gogo->add_statement(key);

  // Loop over the array elements.
  // for i = range a
  Type* int_type = Type::lookup_integer_type("int");
  Temporary_statement* index = Statement::make_temporary(int_type, NULL, bloc);
  gogo->add_statement(index);

  Expression* iref = Expression::make_temporary_reference(index, bloc);
  Expression* aref = Expression::make_var_reference(key_arg, bloc);
  Type* pt = Type::make_pointer_type(name != NULL
				     ? static_cast<Type*>(name)
				     : static_cast<Type*>(this));
  aref = Expression::make_cast(pt, aref, bloc);
  For_range_statement* for_range = Statement::make_for_range_statement(iref,
								       NULL,
								       aref,
								       bloc);

  gogo->start_block(bloc);

  // Get the hash function for the element type.
  Named_object* hash_fn;
  Named_object* equal_fn;
  this->element_type_->type_functions(gogo, this->element_type_->named_type(),
				      hash_fntype, equal_fntype, &hash_fn,
				      &equal_fn);

  // Get a pointer to this element in the loop.
  Expression* subkey = Expression::make_temporary_reference(key, bloc);
  subkey = Expression::make_cast(key_arg_type, subkey, bloc);

  // Get the size of each element.
  Expression* ele_size = Expression::make_type_info(this->element_type_,
						    Expression::TYPE_INFO_SIZE);

  // Get the hash of this element, passing retval as the seed.
  ref = Expression::make_temporary_reference(retval, bloc);
  Expression_list* args = new Expression_list();
  args->push_back(subkey);
  args->push_back(ref);
  Expression* func = Expression::make_func_reference(hash_fn, NULL, bloc);
  Expression* call = Expression::make_call(func, args, false, bloc);

  // Set retval to the result.
  Temporary_reference_expression* tref =
    Expression::make_temporary_reference(retval, bloc);
  tref->set_is_lvalue();
  Statement* s = Statement::make_assignment(tref, call, bloc);
  gogo->add_statement(s);

  // Increase the element pointer.
  tref = Expression::make_temporary_reference(key, bloc);
  tref->set_is_lvalue();
  s = Statement::make_assignment_operation(OPERATOR_PLUSEQ, tref, ele_size,
					   bloc);
  Block* statements = gogo->finish_block(bloc);

  for_range->add_statements(statements);
  gogo->add_statement(for_range);

  // Return retval to the caller of the hash function.
  Expression_list* vals = new Expression_list();
  ref = Expression::make_temporary_reference(retval, bloc);
  vals->push_back(ref);
  s = Statement::make_return_statement(vals, bloc);
  gogo->add_statement(s);
}

// Write the equality function for an array which can not use the
// identity function.

void
Array_type::write_equal_function(Gogo* gogo, Named_type* name)
{
  Location bloc = Linemap::predeclared_location();

  // The pointers to the arrays we are going to compare.
  Named_object* key1_arg = gogo->lookup("key1", NULL);
  Named_object* key2_arg = gogo->lookup("key2", NULL);
  go_assert(key1_arg != NULL && key2_arg != NULL);

  // Build temporaries for the keys with the right types.
  Type* pt = Type::make_pointer_type(name != NULL
				     ? static_cast<Type*>(name)
				     : static_cast<Type*>(this));

  Expression* ref = Expression::make_var_reference(key1_arg, bloc);
  ref = Expression::make_unsafe_cast(pt, ref, bloc);
  Temporary_statement* p1 = Statement::make_temporary(pt, ref, bloc);
  gogo->add_statement(p1);

  ref = Expression::make_var_reference(key2_arg, bloc);
  ref = Expression::make_unsafe_cast(pt, ref, bloc);
  Temporary_statement* p2 = Statement::make_temporary(pt, ref, bloc);
  gogo->add_statement(p2);

  // Loop over the array elements.
  // for i = range a
  Type* int_type = Type::lookup_integer_type("int");
  Temporary_statement* index = Statement::make_temporary(int_type, NULL, bloc);
  gogo->add_statement(index);

  Expression* iref = Expression::make_temporary_reference(index, bloc);
  Expression* aref = Expression::make_temporary_reference(p1, bloc);
  For_range_statement* for_range = Statement::make_for_range_statement(iref,
								       NULL,
								       aref,
								       bloc);

  gogo->start_block(bloc);

  // Compare element in P1 and P2.
  Expression* e1 = Expression::make_temporary_reference(p1, bloc);
  e1 = Expression::make_dereference(e1, Expression::NIL_CHECK_DEFAULT, bloc);
  ref = Expression::make_temporary_reference(index, bloc);
  e1 = Expression::make_array_index(e1, ref, NULL, NULL, bloc);

  Expression* e2 = Expression::make_temporary_reference(p2, bloc);
  e2 = Expression::make_dereference(e2, Expression::NIL_CHECK_DEFAULT, bloc);
  ref = Expression::make_temporary_reference(index, bloc);
  e2 = Expression::make_array_index(e2, ref, NULL, NULL, bloc);

  Expression* cond = Expression::make_binary(OPERATOR_NOTEQ, e1, e2, bloc);

  // If the elements are not equal, return false.
  gogo->start_block(bloc);
  Expression_list* vals = new Expression_list();
  vals->push_back(Expression::make_boolean(false, bloc));
  Statement* s = Statement::make_return_statement(vals, bloc);
  gogo->add_statement(s);
  Block* then_block = gogo->finish_block(bloc);

  s = Statement::make_if_statement(cond, then_block, NULL, bloc);
  gogo->add_statement(s);

  Block* statements = gogo->finish_block(bloc);

  for_range->add_statements(statements);
  gogo->add_statement(for_range);

  // All the elements are equal, so return true.
  vals = new Expression_list();
  vals->push_back(Expression::make_boolean(true, bloc));
  s = Statement::make_return_statement(vals, bloc);
  gogo->add_statement(s);
}

// Get the backend representation of the fields of a slice.  This is
// not declared in types.h so that types.h doesn't have to #include
// backend.h.
//
// We use int for the count and capacity fields.  This matches 6g.
// The language more or less assumes that we can't allocate space of a
// size which does not fit in int.

static void
get_backend_slice_fields(Gogo* gogo, Array_type* type, bool use_placeholder,
			 std::vector<Backend::Btyped_identifier>* bfields)
{
  bfields->resize(3);

  Type* pet = Type::make_pointer_type(type->element_type());
  Btype* pbet = (use_placeholder
		 ? pet->get_backend_placeholder(gogo)
		 : pet->get_backend(gogo));
  Location ploc = Linemap::predeclared_location();

  Backend::Btyped_identifier* p = &(*bfields)[0];
  p->name = "__values";
  p->btype = pbet;
  p->location = ploc;

  Type* int_type = Type::lookup_integer_type("int");

  p = &(*bfields)[1];
  p->name = "__count";
  p->btype = int_type->get_backend(gogo);
  p->location = ploc;

  p = &(*bfields)[2];
  p->name = "__capacity";
  p->btype = int_type->get_backend(gogo);
  p->location = ploc;
}

// 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*
Array_type::do_get_backend(Gogo* gogo)
{
  if (this->length_ == NULL)
    {
      std::vector<Backend::Btyped_identifier> bfields;
      get_backend_slice_fields(gogo, this, false, &bfields);
      return gogo->backend()->struct_type(bfields);
    }
  else
    {
      Btype* element = this->get_backend_element(gogo, false);
      Bexpression* len = this->get_backend_length(gogo);
      return gogo->backend()->array_type(element, len);
    }
}

// Return the backend representation of the element type.

Btype*
Array_type::get_backend_element(Gogo* gogo, bool use_placeholder)
{
  if (use_placeholder)
    return this->element_type_->get_backend_placeholder(gogo);
  else
    return this->element_type_->get_backend(gogo);
}

// Return the backend representation of the length. The length may be
// computed using a function call, so we must only evaluate it once.

Bexpression*
Array_type::get_backend_length(Gogo* gogo)
{
  go_assert(this->length_ != NULL);
  if (this->blength_ == NULL)
    {
      if (this->length_->is_error_expression())
        {
          this->blength_ = gogo->backend()->error_expression();
          return this->blength_;
        }
      Numeric_constant nc;
      mpz_t val;
      if (this->length_->numeric_constant_value(&nc) && nc.to_int(&val))
	{
	  if (mpz_sgn(val) < 0)
	    {
	      this->blength_ = gogo->backend()->error_expression();
	      return this->blength_;
	    }
	  Type* t = nc.type();
	  if (t == NULL)
	    t = Type::lookup_integer_type("int");
	  else if (t->is_abstract())
	    t = t->make_non_abstract_type();
          Btype* btype = t->get_backend(gogo);
          this->blength_ =
	    gogo->backend()->integer_constant_expression(btype, val);
	  mpz_clear(val);
	}
      else
	{
	  // 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_ = this->length_->get_backend(&context);

	  Btype* ibtype = Type::lookup_integer_type("int")->get_backend(gogo);
	  this->blength_ =
	    gogo->backend()->convert_expression(ibtype, this->blength_,
						this->length_->location());
	}
    }
  return this->blength_;
}

// Finish backend representation of the array.

void
Array_type::finish_backend_element(Gogo* gogo)
{
  Type* et = this->array_type()->element_type();
  et->get_backend(gogo);
  if (this->is_slice_type())
    {
      // This relies on the fact that we always use the same
      // structure for a pointer to any given type.
      Type* pet = Type::make_pointer_type(et);
      pet->get_backend(gogo);
    }
}

// Return an expression for a pointer to the values in ARRAY.

Expression*
Array_type::get_value_pointer(Gogo*, Expression* array, bool is_lvalue) const
{
  if (this->length() != NULL)
    {
      // Fixed array.
      go_assert(array->type()->array_type() != NULL);
      Type* etype = array->type()->array_type()->element_type();
      array = Expression::make_unary(OPERATOR_AND, array, array->location());
      return Expression::make_cast(Type::make_pointer_type(etype), array,
                                   array->location());
    }

  // Slice.

  if (is_lvalue)
    {
      Temporary_reference_expression* tref =
          array->temporary_reference_expression();
      Var_expression* ve = array->var_expression();
      if (tref != NULL)
        {
          tref = tref->copy()->temporary_reference_expression();
          tref->set_is_lvalue();
          array = tref;
        }
      else if (ve != NULL)
        {
          ve = new Var_expression(ve->named_object(), ve->location());
          array = ve;
        }
    }

  return Expression::make_slice_info(array,
                                     Expression::SLICE_INFO_VALUE_POINTER,
                                     array->location());
}

// Return an expression for the length of the array ARRAY which has this
// type.

Expression*
Array_type::get_length(Gogo*, Expression* array) const
{
  if (this->length_ != NULL)
    return this->length_;

  // This is a slice.  We need to read the length field.
  return Expression::make_slice_info(array, Expression::SLICE_INFO_LENGTH,
                                     array->location());
}

// Return an expression for the capacity of the array ARRAY which has this
// type.

Expression*
Array_type::get_capacity(Gogo*, Expression* array) const
{
  if (this->length_ != NULL)
    return this->length_;

  // This is a slice.  We need to read the capacity field.
  return Expression::make_slice_info(array, Expression::SLICE_INFO_CAPACITY,
                                     array->location());
}

// Export.

void
Array_type::do_export(Export* exp) const
{
  exp->write_c_string("[");
  if (this->length_ != NULL)
    this->length_->export_expression(exp);
  exp->write_c_string("] ");
  exp->write_type(this->element_type_);
}

// Import.

Array_type*
Array_type::do_import(Import* imp)
{
  imp->require_c_string("[");
  Expression* length;
  if (imp->peek_char() == ']')
    length = NULL;
  else
    length = Expression::import_expression(imp);
  imp->require_c_string("] ");
  Type* element_type = imp->read_type();
  return Type::make_array_type(element_type, length);
}

// The type of an array type descriptor.

Type*
Array_type::make_array_type_descriptor_type()
{
  static Type* ret;
  if (ret == NULL)
    {
      Type* tdt = Type::make_type_descriptor_type();
      Type* ptdt = Type::make_type_descriptor_ptr_type();

      Type* uintptr_type = Type::lookup_integer_type("uintptr");

      Struct_type* sf =
	Type::make_builtin_struct_type(4,
				       "", tdt,
				       "elem", ptdt,
				       "slice", ptdt,
				       "len", uintptr_type);

      ret = Type::make_builtin_named_type("ArrayType", sf);
    }

  return ret;
}

// The type of an slice type descriptor.

Type*
Array_type::make_slice_type_descriptor_type()
{
  static Type* ret;
  if (ret == NULL)
    {
      Type* tdt = Type::make_type_descriptor_type();
      Type* ptdt = Type::make_type_descriptor_ptr_type();

      Struct_type* sf =
	Type::make_builtin_struct_type(2,
				       "", tdt,
				       "elem", ptdt);

      ret = Type::make_builtin_named_type("SliceType", sf);
    }

  return ret;
}

// Build a type descriptor for an array/slice type.

Expression*
Array_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  if (this->length_ != NULL)
    return this->array_type_descriptor(gogo, name);
  else
    return this->slice_type_descriptor(gogo, name);
}

// Build a type descriptor for an array type.

Expression*
Array_type::array_type_descriptor(Gogo* gogo, Named_type* name)
{
  Location bloc = Linemap::predeclared_location();

  Type* atdt = Array_type::make_array_type_descriptor_type();

  const Struct_field_list* fields = atdt->struct_type()->fields();

  Expression_list* vals = new Expression_list();
  vals->reserve(3);

  Struct_field_list::const_iterator p = fields->begin();
  go_assert(p->is_field_name("_type"));
  vals->push_back(this->type_descriptor_constructor(gogo,
						    RUNTIME_TYPE_KIND_ARRAY,
						    name, NULL, true));

  ++p;
  go_assert(p->is_field_name("elem"));
  vals->push_back(Expression::make_type_descriptor(this->element_type_, bloc));

  ++p;
  go_assert(p->is_field_name("slice"));
  Type* slice_type = Type::make_array_type(this->element_type_, NULL);
  vals->push_back(Expression::make_type_descriptor(slice_type, bloc));

  ++p;
  go_assert(p->is_field_name("len"));
  vals->push_back(Expression::make_cast(p->type(), this->length_, bloc));

  ++p;
  go_assert(p == fields->end());

  return Expression::make_struct_composite_literal(atdt, vals, bloc);
}

// Build a type descriptor for a slice type.

Expression*
Array_type::slice_type_descriptor(Gogo* gogo, Named_type* name)
{
  Location bloc = Linemap::predeclared_location();

  Type* stdt = Array_type::make_slice_type_descriptor_type();

  const Struct_field_list* fields = stdt->struct_type()->fields();

  Expression_list* vals = new Expression_list();
  vals->reserve(2);

  Struct_field_list::const_iterator p = fields->begin();
  go_assert(p->is_field_name("_type"));
  vals->push_back(this->type_descriptor_constructor(gogo,
						    RUNTIME_TYPE_KIND_SLICE,
						    name, NULL, true));

  ++p;
  go_assert(p->is_field_name("elem"));
  vals->push_back(Expression::make_type_descriptor(this->element_type_, bloc));

  ++p;
  go_assert(p == fields->end());

  return Expression::make_struct_composite_literal(stdt, vals, bloc);
}

// Reflection string.

void
Array_type::do_reflection(Gogo* gogo, std::string* ret) const
{
  ret->push_back('[');
  if (this->length_ != NULL)
    {
      Numeric_constant nc;
      if (!this->length_->numeric_constant_value(&nc))
	{
	  go_assert(saw_errors());
	  return;
	}
      mpz_t val;
      if (!nc.to_int(&val))
	{
	  go_assert(saw_errors());
	  return;
	}
      char* s = mpz_get_str(NULL, 10, val);
      ret->append(s);
      free(s);
      mpz_clear(val);
    }
  ret->push_back(']');

  this->append_reflection(this->element_type_, gogo, ret);
}

// Make an array type.

Array_type*
Type::make_array_type(Type* element_type, Expression* length)
{
  return new Array_type(element_type, length);
}

// Class Map_type.

Named_object* Map_type::zero_value;
int64_t Map_type::zero_value_size;
int64_t Map_type::zero_value_align;

// If this map requires the "fat" functions, return the pointer to
// pass as the zero value to those functions.  Otherwise, in the
// normal case, return NULL.  The map requires the "fat" functions if
// the value size is larger than max_zero_size bytes.  max_zero_size
// must match maxZero in libgo/go/runtime/hashmap.go.

Expression*
Map_type::fat_zero_value(Gogo* gogo)
{
  int64_t valsize;
  if (!this->val_type_->backend_type_size(gogo, &valsize))
    {
      go_assert(saw_errors());
      return NULL;
    }
  if (valsize <= Map_type::max_zero_size)
    return NULL;

  if (Map_type::zero_value_size < valsize)
    Map_type::zero_value_size = valsize;

  int64_t valalign;
  if (!this->val_type_->backend_type_align(gogo, &valalign))
    {
      go_assert(saw_errors());
      return NULL;
    }

  if (Map_type::zero_value_align < valalign)
    Map_type::zero_value_align = valalign;

  Location bloc = Linemap::predeclared_location();

  if (Map_type::zero_value == NULL)
    {
      // The final type will be set in backend_zero_value.
      Type* uint8_type = Type::lookup_integer_type("uint8");
      Expression* size = Expression::make_integer_ul(0, NULL, bloc);
      Array_type* array_type = Type::make_array_type(uint8_type, size);
      array_type->set_is_array_incomparable();
      Variable* var = new Variable(array_type, NULL, true, false, false, bloc);
      std::string name = gogo->map_zero_value_name();
      Map_type::zero_value = Named_object::make_variable(name, NULL, var);
    }

  Expression* z = Expression::make_var_reference(Map_type::zero_value, bloc);
  z = Expression::make_unary(OPERATOR_AND, z, bloc);
  Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
  z = Expression::make_cast(unsafe_ptr_type, z, bloc);
  return z;
}

// Return whether VAR is the map zero value.

bool
Map_type::is_zero_value(Variable* var)
{
  return (Map_type::zero_value != NULL
	  && Map_type::zero_value->var_value() == var);
}

// Return the backend representation for the zero value.

Bvariable*
Map_type::backend_zero_value(Gogo* gogo)
{
  Location bloc = Linemap::predeclared_location();

  go_assert(Map_type::zero_value != NULL);

  Type* uint8_type = Type::lookup_integer_type("uint8");
  Btype* buint8_type = uint8_type->get_backend(gogo);

  Type* int_type = Type::lookup_integer_type("int");

  Expression* e = Expression::make_integer_int64(Map_type::zero_value_size,
						 int_type, bloc);
  Translate_context context(gogo, NULL, NULL, NULL);
  Bexpression* blength = e->get_backend(&context);

  Btype* barray_type = gogo->backend()->array_type(buint8_type, blength);

  std::string zname = Map_type::zero_value->name();
  std::string asm_name(go_selectively_encode_id(zname));
  Bvariable* zvar =
      gogo->backend()->implicit_variable(zname, asm_name,
                                         barray_type, false, false, true,
					 Map_type::zero_value_align);
  gogo->backend()->implicit_variable_set_init(zvar, zname, barray_type,
					      false, false, true, NULL);
  return zvar;
}

// Traversal.

int
Map_type::do_traverse(Traverse* traverse)
{
  if (Type::traverse(this->key_type_, traverse) == TRAVERSE_EXIT
      || Type::traverse(this->val_type_, traverse) == TRAVERSE_EXIT)
    return TRAVERSE_EXIT;
  return TRAVERSE_CONTINUE;
}

// Check that the map type is OK.

bool
Map_type::do_verify()
{
  // The runtime support uses "map[void]void".
  if (!this->key_type_->is_comparable() && !this->key_type_->is_void_type())
    go_error_at(this->location_, "invalid map key type");
  if (!this->key_type_->in_heap())
    go_error_at(this->location_, "go:notinheap map key not allowed");
  if (!this->val_type_->in_heap())
    go_error_at(this->location_, "go:notinheap map value not allowed");
  return true;
}

// Whether two map types are identical.

bool
Map_type::is_identical(const Map_type* t, int flags) const
{
  return (Type::are_identical(this->key_type(), t->key_type(), flags, NULL)
	  && Type::are_identical(this->val_type(), t->val_type(), flags,
				 NULL));
}

// Hash code.

unsigned int
Map_type::do_hash_for_method(Gogo* gogo, int flags) const
{
  return (this->key_type_->hash_for_method(gogo, flags)
	  + this->val_type_->hash_for_method(gogo, flags)
	  + 2);
}

// Get the backend representation for a map type.  A map type is
// represented as a pointer to a struct.  The struct is hmap in
// runtime/hashmap.go.

Btype*
Map_type::do_get_backend(Gogo* gogo)
{
  static Btype* backend_map_type;
  if (backend_map_type == NULL)
    {
      std::vector<Backend::Btyped_identifier> bfields(9);

      Location bloc = Linemap::predeclared_location();

      Type* int_type = Type::lookup_integer_type("int");
      bfields[0].name = "count";
      bfields[0].btype = int_type->get_backend(gogo);
      bfields[0].location = bloc;

      Type* uint8_type = Type::lookup_integer_type("uint8");
      bfields[1].name = "flags";
      bfields[1].btype = uint8_type->get_backend(gogo);
      bfields[1].location = bloc;

      bfields[2].name = "B";
      bfields[2].btype = bfields[1].btype;
      bfields[2].location = bloc;

      Type* uint16_type = Type::lookup_integer_type("uint16");
      bfields[3].name = "noverflow";
      bfields[3].btype = uint16_type->get_backend(gogo);
      bfields[3].location = bloc;

      Type* uint32_type = Type::lookup_integer_type("uint32");
      bfields[4].name = "hash0";
      bfields[4].btype = uint32_type->get_backend(gogo);
      bfields[4].location = bloc;

      Btype* bvt = gogo->backend()->void_type();
      Btype* bpvt = gogo->backend()->pointer_type(bvt);
      bfields[5].name = "buckets";
      bfields[5].btype = bpvt;
      bfields[5].location = bloc;

      bfields[6].name = "oldbuckets";
      bfields[6].btype = bpvt;
      bfields[6].location = bloc;

      Type* uintptr_type = Type::lookup_integer_type("uintptr");
      bfields[7].name = "nevacuate";
      bfields[7].btype = uintptr_type->get_backend(gogo);
      bfields[7].location = bloc;

      bfields[8].name = "extra";
      bfields[8].btype = bpvt;
      bfields[8].location = bloc;

      Btype *bt = gogo->backend()->struct_type(bfields);
      bt = gogo->backend()->named_type("runtime.hmap", bt, bloc);
      backend_map_type = gogo->backend()->pointer_type(bt);
    }
  return backend_map_type;
}

// The type of a map type descriptor.

Type*
Map_type::make_map_type_descriptor_type()
{
  static Type* ret;
  if (ret == NULL)
    {
      Type* tdt = Type::make_type_descriptor_type();
      Type* ptdt = Type::make_type_descriptor_ptr_type();
      Type* uint8_type = Type::lookup_integer_type("uint8");
      Type* uint16_type = Type::lookup_integer_type("uint16");
      Type* bool_type = Type::lookup_bool_type();

      Struct_type* sf =
	Type::make_builtin_struct_type(11,
				       "", tdt,
				       "key", ptdt,
				       "elem", ptdt,
				       "bucket", ptdt,
				       "keysize", uint8_type,
				       "indirectkey", bool_type,
				       "valuesize", uint8_type,
				       "indirectvalue", bool_type,
				       "bucketsize", uint16_type,
				       "reflexivekey", bool_type,
				       "needkeyupdate", bool_type);

      ret = Type::make_builtin_named_type("MapType", sf);
    }

  return ret;
}

// Build a type descriptor for a map type.

Expression*
Map_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  Location bloc = Linemap::predeclared_location();

  Type* mtdt = Map_type::make_map_type_descriptor_type();
  Type* uint8_type = Type::lookup_integer_type("uint8");
  Type* uint16_type = Type::lookup_integer_type("uint16");

  int64_t keysize;
  if (!this->key_type_->backend_type_size(gogo, &keysize))
    {
      go_error_at(this->location_, "error determining map key type size");
      return Expression::make_error(this->location_);
    }

  int64_t valsize;
  if (!this->val_type_->backend_type_size(gogo, &valsize))
    {
      go_error_at(this->location_, "error determining map value type size");
      return Expression::make_error(this->location_);
    }

  int64_t ptrsize;
  if (!Type::make_pointer_type(uint8_type)->backend_type_size(gogo, &ptrsize))
    {
      go_assert(saw_errors());
      return Expression::make_error(this->location_);
    }

  Type* bucket_type = this->bucket_type(gogo, keysize, valsize);
  if (bucket_type == NULL)
    {
      go_assert(saw_errors());
      return Expression::make_error(this->location_);
    }

  int64_t bucketsize;
  if (!bucket_type->backend_type_size(gogo, &bucketsize))
    {
      go_assert(saw_errors());
      return Expression::make_error(this->location_);
    }

  const Struct_field_list* fields = mtdt->struct_type()->fields();

  Expression_list* vals = new Expression_list();
  vals->reserve(12);

  Struct_field_list::const_iterator p = fields->begin();
  go_assert(p->is_field_name("_type"));
  vals->push_back(this->type_descriptor_constructor(gogo,
						    RUNTIME_TYPE_KIND_MAP,
						    name, NULL, true));

  ++p;
  go_assert(p->is_field_name("key"));
  vals->push_back(Expression::make_type_descriptor(this->key_type_, bloc));

  ++p;
  go_assert(p->is_field_name("elem"));
  vals->push_back(Expression::make_type_descriptor(this->val_type_, bloc));

  ++p;
  go_assert(p->is_field_name("bucket"));
  vals->push_back(Expression::make_type_descriptor(bucket_type, bloc));

  ++p;
  go_assert(p->is_field_name("keysize"));
  if (keysize > Map_type::max_key_size)
    vals->push_back(Expression::make_integer_int64(ptrsize, uint8_type, bloc));
  else
    vals->push_back(Expression::make_integer_int64(keysize, uint8_type, bloc));

  ++p;
  go_assert(p->is_field_name("indirectkey"));
  vals->push_back(Expression::make_boolean(keysize > Map_type::max_key_size,
					   bloc));

  ++p;
  go_assert(p->is_field_name("valuesize"));
  if (valsize > Map_type::max_val_size)
    vals->push_back(Expression::make_integer_int64(ptrsize, uint8_type, bloc));
  else
    vals->push_back(Expression::make_integer_int64(valsize, uint8_type, bloc));

  ++p;
  go_assert(p->is_field_name("indirectvalue"));
  vals->push_back(Expression::make_boolean(valsize > Map_type::max_val_size,
					   bloc));

  ++p;
  go_assert(p->is_field_name("bucketsize"));
  vals->push_back(Expression::make_integer_int64(bucketsize, uint16_type,
						 bloc));

  ++p;
  go_assert(p->is_field_name("reflexivekey"));
  vals->push_back(Expression::make_boolean(this->key_type_->is_reflexive(),
					   bloc));

  ++p;
  go_assert(p->is_field_name("needkeyupdate"));
  vals->push_back(Expression::make_boolean(this->key_type_->needs_key_update(),
					   bloc));

  ++p;
  go_assert(p == fields->end());

  return Expression::make_struct_composite_literal(mtdt, vals, bloc);
}

// Return the bucket type to use for a map type.  This must correspond
// to libgo/go/runtime/hashmap.go.

Type*
Map_type::bucket_type(Gogo* gogo, int64_t keysize, int64_t valsize)
{
  if (this->bucket_type_ != NULL)
    return this->bucket_type_;

  Type* key_type = this->key_type_;
  if (keysize > Map_type::max_key_size)
    key_type = Type::make_pointer_type(key_type);

  Type* val_type = this->val_type_;
  if (valsize > Map_type::max_val_size)
    val_type = Type::make_pointer_type(val_type);

  Expression* bucket_size = Expression::make_integer_ul(Map_type::bucket_size,
							NULL, this->location_);

  Type* uint8_type = Type::lookup_integer_type("uint8");
  Array_type* topbits_type = Type::make_array_type(uint8_type, bucket_size);
  topbits_type->set_is_array_incomparable();
  Array_type* keys_type = Type::make_array_type(key_type, bucket_size);
  keys_type->set_is_array_incomparable();
  Array_type* values_type = Type::make_array_type(val_type, bucket_size);
  values_type->set_is_array_incomparable();

  // If keys and values have no pointers, the map implementation can
  // keep a list of overflow pointers on the side so that buckets can
  // be marked as having no pointers.  Arrange for the bucket to have
  // no pointers by changing the type of the overflow field to uintptr
  // in this case.  See comment on the hmap.overflow field in
  // libgo/go/runtime/hashmap.go.
  Type* overflow_type;
  if (!key_type->has_pointer() && !val_type->has_pointer())
    overflow_type = Type::lookup_integer_type("uintptr");
  else
    {
      // This should really be a pointer to the bucket type itself,
      // but that would require us to construct a Named_type for it to
      // give it a way to refer to itself.  Since nothing really cares
      // (except perhaps for someone using a debugger) just use an
      // unsafe pointer.
      overflow_type = Type::make_pointer_type(Type::make_void_type());
    }

  // Make sure the overflow pointer is the last memory in the struct,
  // because the runtime assumes it can use size-ptrSize as the offset
  // of the overflow pointer.  We double-check that property below
  // once the offsets and size are computed.

  int64_t topbits_field_size, topbits_field_align;
  int64_t keys_field_size, keys_field_align;
  int64_t values_field_size, values_field_align;
  int64_t overflow_field_size, overflow_field_align;
  if (!topbits_type->backend_type_size(gogo, &topbits_field_size)
      || !topbits_type->backend_type_field_align(gogo, &topbits_field_align)
      || !keys_type->backend_type_size(gogo, &keys_field_size)
      || !keys_type->backend_type_field_align(gogo, &keys_field_align)
      || !values_type->backend_type_size(gogo, &values_field_size)
      || !values_type->backend_type_field_align(gogo, &values_field_align)
      || !overflow_type->backend_type_size(gogo, &overflow_field_size)
      || !overflow_type->backend_type_field_align(gogo, &overflow_field_align))
    {
      go_assert(saw_errors());
      return NULL;
    }

  Struct_type* ret;
  int64_t max_align = std::max(std::max(topbits_field_align, keys_field_align),
			       values_field_align);
  if (max_align <= overflow_field_align)
    ret =  make_builtin_struct_type(4,
				    "topbits", topbits_type,
				    "keys", keys_type,
				    "values", values_type,
				    "overflow", overflow_type);
  else
    {
      size_t off = topbits_field_size;
      off = ((off + keys_field_align - 1)
	     &~ static_cast<size_t>(keys_field_align - 1));
      off += keys_field_size;
      off = ((off + values_field_align - 1)
	     &~ static_cast<size_t>(values_field_align - 1));
      off += values_field_size;

      int64_t padded_overflow_field_size =
	((overflow_field_size + max_align - 1)
	 &~ static_cast<size_t>(max_align - 1));

      size_t ovoff = off;
      ovoff = ((ovoff + max_align - 1)
	       &~ static_cast<size_t>(max_align - 1));
      size_t pad = (ovoff - off
		    + padded_overflow_field_size - overflow_field_size);

      Expression* pad_expr = Expression::make_integer_ul(pad, NULL,
							 this->location_);
      Array_type* pad_type = Type::make_array_type(uint8_type, pad_expr);
      pad_type->set_is_array_incomparable();

      ret = make_builtin_struct_type(5,
				     "topbits", topbits_type,
				     "keys", keys_type,
				     "values", values_type,
				     "pad", pad_type,
				     "overflow", overflow_type);
    }

  // Verify that the overflow field is just before the end of the
  // bucket type.

  Btype* btype = ret->get_backend(gogo);
  int64_t offset = gogo->backend()->type_field_offset(btype,
						      ret->field_count() - 1);
  int64_t size;
  if (!ret->backend_type_size(gogo, &size))
    {
      go_assert(saw_errors());
      return NULL;
    }

  int64_t ptr_size;
  if (!Type::make_pointer_type(uint8_type)->backend_type_size(gogo, &ptr_size))
    {
      go_assert(saw_errors());
      return NULL;
    }

  go_assert(offset + ptr_size == size);

  ret->set_is_struct_incomparable();

  this->bucket_type_ = ret;
  return ret;
}

// Return the hashmap type for a map type.

Type*
Map_type::hmap_type(Type* bucket_type)
{
  if (this->hmap_type_ != NULL)
    return this->hmap_type_;

  Type* int_type = Type::lookup_integer_type("int");
  Type* uint8_type = Type::lookup_integer_type("uint8");
  Type* uint16_type = Type::lookup_integer_type("uint16");
  Type* uint32_type = Type::lookup_integer_type("uint32");
  Type* uintptr_type = Type::lookup_integer_type("uintptr");
  Type* void_ptr_type = Type::make_pointer_type(Type::make_void_type());

  Type* ptr_bucket_type = Type::make_pointer_type(bucket_type);

  Struct_type* ret = make_builtin_struct_type(9,
					      "count", int_type,
					      "flags", uint8_type,
					      "B", uint8_type,
					      "noverflow", uint16_type,
					      "hash0", uint32_type,
					      "buckets", ptr_bucket_type,
					      "oldbuckets", ptr_bucket_type,
					      "nevacuate", uintptr_type,
					      "extra", void_ptr_type);
  ret->set_is_struct_incomparable();
  this->hmap_type_ = ret;
  return ret;
}

// Return the iterator type for a map type.  This is the type of the
// value used when doing a range over a map.

Type*
Map_type::hiter_type(Gogo* gogo)
{
  if (this->hiter_type_ != NULL)
    return this->hiter_type_;

  int64_t keysize, valsize;
  if (!this->key_type_->backend_type_size(gogo, &keysize)
      || !this->val_type_->backend_type_size(gogo, &valsize))
    {
      go_assert(saw_errors());
      return NULL;
    }

  Type* key_ptr_type = Type::make_pointer_type(this->key_type_);
  Type* val_ptr_type = Type::make_pointer_type(this->val_type_);
  Type* uint8_type = Type::lookup_integer_type("uint8");
  Type* uint8_ptr_type = Type::make_pointer_type(uint8_type);
  Type* uintptr_type = Type::lookup_integer_type("uintptr");
  Type* bucket_type = this->bucket_type(gogo, keysize, valsize);
  Type* bucket_ptr_type = Type::make_pointer_type(bucket_type);
  Type* hmap_type = this->hmap_type(bucket_type);
  Type* hmap_ptr_type = Type::make_pointer_type(hmap_type);
  Type* void_ptr_type = Type::make_pointer_type(Type::make_void_type());
  Type* bool_type = Type::lookup_bool_type();

  Struct_type* ret = make_builtin_struct_type(15,
					      "key", key_ptr_type,
					      "val", val_ptr_type,
					      "t", uint8_ptr_type,
					      "h", hmap_ptr_type,
					      "buckets", bucket_ptr_type,
					      "bptr", bucket_ptr_type,
					      "overflow", void_ptr_type,
					      "oldoverflow", void_ptr_type,
					      "startBucket", uintptr_type,
					      "offset", uint8_type,
					      "wrapped", bool_type,
					      "B", uint8_type,
					      "i", uint8_type,
					      "bucket", uintptr_type,
					      "checkBucket", uintptr_type);
  ret->set_is_struct_incomparable();
  this->hiter_type_ = ret;
  return ret;
}

// Reflection string for a map.

void
Map_type::do_reflection(Gogo* gogo, std::string* ret) const
{
  ret->append("map[");
  this->append_reflection(this->key_type_, gogo, ret);
  ret->append("]");
  this->append_reflection(this->val_type_, gogo, ret);
}

// Export a map type.

void
Map_type::do_export(Export* exp) const
{
  exp->write_c_string("map [");
  exp->write_type(this->key_type_);
  exp->write_c_string("] ");
  exp->write_type(this->val_type_);
}

// Import a map type.

Map_type*
Map_type::do_import(Import* imp)
{
  imp->require_c_string("map [");
  Type* key_type = imp->read_type();
  imp->require_c_string("] ");
  Type* val_type = imp->read_type();
  return Type::make_map_type(key_type, val_type, imp->location());
}

// Make a map type.

Map_type*
Type::make_map_type(Type* key_type, Type* val_type, Location location)
{
  return new Map_type(key_type, val_type, location);
}

// Class Channel_type.

// Verify.

bool
Channel_type::do_verify()
{
  // We have no location for this error, but this is not something the
  // ordinary user will see.
  if (!this->element_type_->in_heap())
    go_error_at(Linemap::unknown_location(),
		"chan of go:notinheap type not allowed");
  return true;
}

// Hash code.

unsigned int
Channel_type::do_hash_for_method(Gogo* gogo, int flags) const
{
  unsigned int ret = 0;
  if (this->may_send_)
    ret += 1;
  if (this->may_receive_)
    ret += 2;
  if (this->element_type_ != NULL)
    ret += this->element_type_->hash_for_method(gogo, flags) << 2;
  return ret << 3;
}

// Whether this type is the same as T.

bool
Channel_type::is_identical(const Channel_type* t, int flags) const
{
  if (!Type::are_identical(this->element_type(), t->element_type(), flags,
			   NULL))
    return false;
  return (this->may_send_ == t->may_send_
	  && this->may_receive_ == t->may_receive_);
}

// 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*
Channel_type::do_get_backend(Gogo* gogo)
{
  static Btype* backend_channel_type;
  if (backend_channel_type == NULL)
    {
      std::vector<Backend::Btyped_identifier> bfields;
      Btype* bt = gogo->backend()->struct_type(bfields);
      bt = gogo->backend()->named_type("__go_channel", bt,
                                       Linemap::predeclared_location());
      backend_channel_type = gogo->backend()->pointer_type(bt);
    }
  return backend_channel_type;
}

// Build a type descriptor for a channel type.

Type*
Channel_type::make_chan_type_descriptor_type()
{
  static Type* ret;
  if (ret == NULL)
    {
      Type* tdt = Type::make_type_descriptor_type();
      Type* ptdt = Type::make_type_descriptor_ptr_type();

      Type* uintptr_type = Type::lookup_integer_type("uintptr");

      Struct_type* sf =
	Type::make_builtin_struct_type(3,
				       "", tdt,
				       "elem", ptdt,
				       "dir", uintptr_type);

      ret = Type::make_builtin_named_type("ChanType", sf);
    }

  return ret;
}

// Build a type descriptor for a map type.

Expression*
Channel_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  Location bloc = Linemap::predeclared_location();

  Type* ctdt = Channel_type::make_chan_type_descriptor_type();

  const Struct_field_list* fields = ctdt->struct_type()->fields();

  Expression_list* vals = new Expression_list();
  vals->reserve(3);

  Struct_field_list::const_iterator p = fields->begin();
  go_assert(p->is_field_name("_type"));
  vals->push_back(this->type_descriptor_constructor(gogo,
						    RUNTIME_TYPE_KIND_CHAN,
						    name, NULL, true));

  ++p;
  go_assert(p->is_field_name("elem"));
  vals->push_back(Expression::make_type_descriptor(this->element_type_, bloc));

  ++p;
  go_assert(p->is_field_name("dir"));
  // These bits must match the ones in libgo/runtime/go-type.h.
  int val = 0;
  if (this->may_receive_)
    val |= 1;
  if (this->may_send_)
    val |= 2;
  vals->push_back(Expression::make_integer_ul(val, p->type(), bloc));

  ++p;
  go_assert(p == fields->end());

  return Expression::make_struct_composite_literal(ctdt, vals, bloc);
}

// Reflection string.

void
Channel_type::do_reflection(Gogo* gogo, std::string* ret) const
{
  if (!this->may_send_)
    ret->append("<-");
  ret->append("chan");
  if (!this->may_receive_)
    ret->append("<-");
  ret->push_back(' ');
  this->append_reflection(this->element_type_, gogo, ret);
}

// Export.

void
Channel_type::do_export(Export* exp) const
{
  exp->write_c_string("chan ");
  if (this->may_send_ && !this->may_receive_)
    exp->write_c_string("-< ");
  else if (this->may_receive_ && !this->may_send_)
    exp->write_c_string("<- ");
  exp->write_type(this->element_type_);
}

// Import.

Channel_type*
Channel_type::do_import(Import* imp)
{
  imp->require_c_string("chan ");

  bool may_send;
  bool may_receive;
  if (imp->match_c_string("-< "))
    {
      imp->advance(3);
      may_send = true;
      may_receive = false;
    }
  else if (imp->match_c_string("<- "))
    {
      imp->advance(3);
      may_receive = true;
      may_send = false;
    }
  else
    {
      may_send = true;
      may_receive = true;
    }

  Type* element_type = imp->read_type();

  return Type::make_channel_type(may_send, may_receive, element_type);
}

// Return the type that the runtime package uses for one case of a
// select statement.  An array of values of this type is allocated on
// the stack.  This must match scase in libgo/go/runtime/select.go.

Type*
Channel_type::select_case_type()
{
  static Struct_type* scase_type;
  if (scase_type == NULL)
    {
      Type* unsafe_pointer_type =
	Type::make_pointer_type(Type::make_void_type());
      Type* uint16_type = Type::lookup_integer_type("uint16");
      Type* int64_type = Type::lookup_integer_type("int64");
      scase_type =
	Type::make_builtin_struct_type(4,
				       "c", unsafe_pointer_type,
				       "elem", unsafe_pointer_type,
				       "kind", uint16_type,
				       "releasetime", int64_type);
      scase_type->set_is_struct_incomparable();
    }
  return scase_type;
}

// Make a new channel type.

Channel_type*
Type::make_channel_type(bool send, bool receive, Type* element_type)
{
  return new Channel_type(send, receive, element_type);
}

// Class Interface_type.

// Return the list of methods.

const Typed_identifier_list*
Interface_type::methods() const
{
  go_assert(this->methods_are_finalized_ || saw_errors());
  return this->all_methods_;
}

// Return the number of methods.

size_t
Interface_type::method_count() const
{
  go_assert(this->methods_are_finalized_ || saw_errors());
  return this->all_methods_ == NULL ? 0 : this->all_methods_->size();
}

// Traversal.

int
Interface_type::do_traverse(Traverse* traverse)
{
  Typed_identifier_list* methods = (this->methods_are_finalized_
				    ? this->all_methods_
				    : this->parse_methods_);
  if (methods == NULL)
    return TRAVERSE_CONTINUE;
  return methods->traverse(traverse);
}

// Finalize the methods.  This handles interface inheritance.

void
Interface_type::finalize_methods()
{
  if (this->methods_are_finalized_)
    return;
  this->methods_are_finalized_ = true;
  if (this->parse_methods_ == NULL)
    return;

  this->all_methods_ = new Typed_identifier_list();
  this->all_methods_->reserve(this->parse_methods_->size());
  Typed_identifier_list inherit;
  for (Typed_identifier_list::const_iterator pm =
	 this->parse_methods_->begin();
       pm != this->parse_methods_->end();
       ++pm)
    {
      const Typed_identifier* p = &*pm;
      if (p->name().empty())
	inherit.push_back(*p);
      else if (this->find_method(p->name()) == NULL)
	this->all_methods_->push_back(*p);
      else
	go_error_at(p->location(), "duplicate method %qs",
		 Gogo::message_name(p->name()).c_str());
    }

  std::vector<Named_type*> seen;
  seen.reserve(inherit.size());
  bool issued_recursive_error = false;
  while (!inherit.empty())
    {
      Type* t = inherit.back().type();
      Location tl = inherit.back().location();
      inherit.pop_back();

      Interface_type* it = t->interface_type();
      if (it == NULL)
	{
	  if (!t->is_error())
	    go_error_at(tl, "interface contains embedded non-interface");
	  continue;
	}
      if (it == this)
	{
	  if (!issued_recursive_error)
	    {
	      go_error_at(tl, "invalid recursive interface");
	      issued_recursive_error = true;
	    }
	  continue;
	}

      Named_type* nt = t->named_type();
      if (nt != NULL && it->parse_methods_ != NULL)
	{
	  std::vector<Named_type*>::const_iterator q;
	  for (q = seen.begin(); q != seen.end(); ++q)
	    {
	      if (*q == nt)
		{
		  go_error_at(tl, "inherited interface loop");
		  break;
		}
	    }
	  if (q != seen.end())
	    continue;
	  seen.push_back(nt);
	}

      const Typed_identifier_list* imethods = it->parse_methods_;
      if (imethods == NULL)
	continue;
      for (Typed_identifier_list::const_iterator q = imethods->begin();
	   q != imethods->end();
	   ++q)
	{
	  if (q->name().empty())
	    inherit.push_back(*q);
	  else if (this->find_method(q->name()) == NULL)
	    this->all_methods_->push_back(Typed_identifier(q->name(),
							   q->type(), tl));
	  else
	    go_error_at(tl, "inherited method %qs is ambiguous",
		     Gogo::message_name(q->name()).c_str());
	}
    }

  if (!this->all_methods_->empty())
    this->all_methods_->sort_by_name();
  else
    {
      delete this->all_methods_;
      this->all_methods_ = NULL;
    }
}

// Return the method NAME, or NULL.

const Typed_identifier*
Interface_type::find_method(const std::string& name) const
{
  go_assert(this->methods_are_finalized_);
  if (this->all_methods_ == NULL)
    return NULL;
  for (Typed_identifier_list::const_iterator p = this->all_methods_->begin();
       p != this->all_methods_->end();
       ++p)
    if (p->name() == name)
      return &*p;
  return NULL;
}

// Return the method index.

size_t
Interface_type::method_index(const std::string& name) const
{
  go_assert(this->methods_are_finalized_ && this->all_methods_ != NULL);
  size_t ret = 0;
  for (Typed_identifier_list::const_iterator p = this->all_methods_->begin();
       p != this->all_methods_->end();
       ++p, ++ret)
    if (p->name() == name)
      return ret;
  go_unreachable();
}

// Return whether NAME is an unexported method, for better error
// reporting.

bool
Interface_type::is_unexported_method(Gogo* gogo, const std::string& name) const
{
  go_assert(this->methods_are_finalized_);
  if (this->all_methods_ == NULL)
    return false;
  for (Typed_identifier_list::const_iterator p = this->all_methods_->begin();
       p != this->all_methods_->end();
       ++p)
    {
      const std::string& method_name(p->name());
      if (Gogo::is_hidden_name(method_name)
	  && name == Gogo::unpack_hidden_name(method_name)
	  && gogo->pack_hidden_name(name, false) != method_name)
	return true;
    }
  return false;
}

// Whether this type is identical with T.

bool
Interface_type::is_identical(const Interface_type* t, int flags) const
{
  // If methods have not been finalized, then we are asking whether
  // func redeclarations are the same.  This is an error, so for
  // simplicity we say they are never the same.
  if (!this->methods_are_finalized_ || !t->methods_are_finalized_)
    return false;

  // We require the same methods with the same types.  The methods
  // have already been sorted.
  if (this->all_methods_ == NULL || t->all_methods_ == NULL)
    return this->all_methods_ == t->all_methods_;

  if (this->assume_identical(this, t) || t->assume_identical(t, this))
    return true;

  Assume_identical* hold_ai = this->assume_identical_;
  Assume_identical ai;
  ai.t1 = this;
  ai.t2 = t;
  ai.next = hold_ai;
  this->assume_identical_ = &ai;

  Typed_identifier_list::const_iterator p1 = this->all_methods_->begin();
  Typed_identifier_list::const_iterator p2;
  for (p2 = t->all_methods_->begin(); p2 != t->all_methods_->end(); ++p1, ++p2)
    {
      if (p1 == this->all_methods_->end())
	break;
      if (p1->name() != p2->name()
	  || !Type::are_identical(p1->type(), p2->type(), flags, NULL))
	break;
    }

  this->assume_identical_ = hold_ai;

  return p1 == this->all_methods_->end() && p2 == t->all_methods_->end();
}

// Return true if T1 and T2 are assumed to be identical during a type
// comparison.

bool
Interface_type::assume_identical(const Interface_type* t1,
				 const Interface_type* t2) const
{
  for (Assume_identical* p = this->assume_identical_;
       p != NULL;
       p = p->next)
    if ((p->t1 == t1 && p->t2 == t2) || (p->t1 == t2 && p->t2 == t1))
      return true;
  return false;
}

// Whether we can assign the interface type T to this type.  The types
// are known to not be identical.  An interface assignment is only
// permitted if T is known to implement all methods in THIS.
// Otherwise a type guard is required.

bool
Interface_type::is_compatible_for_assign(const Interface_type* t,
					 std::string* reason) const
{
  go_assert(this->methods_are_finalized_ && t->methods_are_finalized_);
  if (this->all_methods_ == NULL)
    return true;
  for (Typed_identifier_list::const_iterator p = this->all_methods_->begin();
       p != this->all_methods_->end();
       ++p)
    {
      const Typed_identifier* m = t->find_method(p->name());
      if (m == NULL)
	{
	  if (reason != NULL)
	    {
	      char buf[200];
	      snprintf(buf, sizeof buf,
		       _("need explicit conversion; missing method %s%s%s"),
		       go_open_quote(), Gogo::message_name(p->name()).c_str(),
		       go_close_quote());
	      reason->assign(buf);
	    }
	  return false;
	}

      std::string subreason;
      if (!Type::are_identical(p->type(), m->type(), Type::COMPARE_TAGS,
			       &subreason))
	{
	  if (reason != NULL)
	    {
	      std::string n = Gogo::message_name(p->name());
	      size_t len = 100 + n.length() + subreason.length();
	      char* buf = new char[len];
	      if (subreason.empty())
		snprintf(buf, len, _("incompatible type for method %s%s%s"),
			 go_open_quote(), n.c_str(), go_close_quote());
	      else
		snprintf(buf, len,
			 _("incompatible type for method %s%s%s (%s)"),
			 go_open_quote(), n.c_str(), go_close_quote(),
			 subreason.c_str());
	      reason->assign(buf);
	      delete[] buf;
	    }
	  return false;
	}
    }

  return true;
}

// Hash code.

unsigned int
Interface_type::do_hash_for_method(Gogo*, int) const
{
  go_assert(this->methods_are_finalized_);
  unsigned int ret = 0;
  if (this->all_methods_ != NULL)
    {
      for (Typed_identifier_list::const_iterator p =
	     this->all_methods_->begin();
	   p != this->all_methods_->end();
	   ++p)
	{
	  ret = Type::hash_string(p->name(), ret);
	  // We don't use the method type in the hash, to avoid
	  // infinite recursion if an interface method uses a type
	  // which is an interface which inherits from the interface
	  // itself.
	  // type T interface { F() interface {T}}
	  ret <<= 1;
	}
    }
  return ret;
}

// Return true if T implements the interface.  If it does not, and
// REASON is not NULL, set *REASON to a useful error message.

bool
Interface_type::implements_interface(const Type* t, std::string* reason) const
{
  go_assert(this->methods_are_finalized_);
  if (this->all_methods_ == NULL)
    return true;

  bool is_pointer = false;
  const Named_type* nt = t->named_type();
  const Struct_type* st = t->struct_type();
  // If we start with a named type, we don't dereference it to find
  // methods.
  if (nt == NULL)
    {
      const Type* pt = t->points_to();
      if (pt != NULL)
	{
	  // If T is a pointer to a named type, then we need to look at
	  // the type to which it points.
	  is_pointer = true;
	  nt = pt->named_type();
	  st = pt->struct_type();
	}
    }

  // If we have a named type, get the methods from it rather than from
  // any struct type.
  if (nt != NULL)
    st = NULL;

  // Only named and struct types have methods.
  if (nt == NULL && st == NULL)
    {
      if (reason != NULL)
	{
	  if (t->points_to() != NULL
	      && t->points_to()->interface_type() != NULL)
	    reason->assign(_("pointer to interface type has no methods"));
	  else
	    reason->assign(_("type has no methods"));
	}
      return false;
    }

  if (nt != NULL ? !nt->has_any_methods() : !st->has_any_methods())
    {
      if (reason != NULL)
	{
	  if (t->points_to() != NULL
	      && t->points_to()->interface_type() != NULL)
	    reason->assign(_("pointer to interface type has no methods"));
	  else
	    reason->assign(_("type has no methods"));
	}
      return false;
    }

  for (Typed_identifier_list::const_iterator p = this->all_methods_->begin();
       p != this->all_methods_->end();
       ++p)
    {
      bool is_ambiguous = false;
      Method* m = (nt != NULL
		   ? nt->method_function(p->name(), &is_ambiguous)
		   : st->method_function(p->name(), &is_ambiguous));
      if (m == NULL)
	{
	  if (reason != NULL)
	    {
	      std::string n = Gogo::message_name(p->name());
	      size_t len = n.length() + 100;
	      char* buf = new char[len];
	      if (is_ambiguous)
		snprintf(buf, len, _("ambiguous method %s%s%s"),
			 go_open_quote(), n.c_str(), go_close_quote());
	      else
		snprintf(buf, len, _("missing method %s%s%s"),
			 go_open_quote(), n.c_str(), go_close_quote());
	      reason->assign(buf);
	      delete[] buf;
	    }
	  return false;
	}

      Function_type *p_fn_type = p->type()->function_type();
      Function_type* m_fn_type = m->type()->function_type();
      go_assert(p_fn_type != NULL && m_fn_type != NULL);
      std::string subreason;
      if (!p_fn_type->is_identical(m_fn_type, true, Type::COMPARE_TAGS,
				   &subreason))
	{
	  if (reason != NULL)
	    {
	      std::string n = Gogo::message_name(p->name());
	      size_t len = 100 + n.length() + subreason.length();
	      char* buf = new char[len];
	      if (subreason.empty())
		snprintf(buf, len, _("incompatible type for method %s%s%s"),
			 go_open_quote(), n.c_str(), go_close_quote());
	      else
		snprintf(buf, len,
			 _("incompatible type for method %s%s%s (%s)"),
			 go_open_quote(), n.c_str(), go_close_quote(),
			 subreason.c_str());
	      reason->assign(buf);
	      delete[] buf;
	    }
	  return false;
	}

      if (!is_pointer && !m->is_value_method())
	{
	  if (reason != NULL)
	    {
	      std::string n = Gogo::message_name(p->name());
	      size_t len = 100 + n.length();
	      char* buf = new char[len];
	      snprintf(buf, len,
		       _("method %s%s%s requires a pointer receiver"),
		       go_open_quote(), n.c_str(), go_close_quote());
	      reason->assign(buf);
	      delete[] buf;
	    }
	  return false;
	}

      // If the magic //go:nointerface comment was used, the method
      // may not be used to implement interfaces.
      if (m->nointerface())
	{
	  if (reason != NULL)
	    {
	      std::string n = Gogo::message_name(p->name());
	      size_t len = 100 + n.length();
	      char* buf = new char[len];
	      snprintf(buf, len,
		       _("method %s%s%s is marked go:nointerface"),
		       go_open_quote(), n.c_str(), go_close_quote());
	      reason->assign(buf);
	      delete[] buf;
	    }
	  return false;
	}
    }

  return true;
}

// Return the backend representation of the empty interface type.  We
// use the same struct for all empty interfaces.

Btype*
Interface_type::get_backend_empty_interface_type(Gogo* gogo)
{
  static Btype* empty_interface_type;
  if (empty_interface_type == NULL)
    {
      std::vector<Backend::Btyped_identifier> bfields(2);

      Location bloc = Linemap::predeclared_location();

      Type* pdt = Type::make_type_descriptor_ptr_type();
      bfields[0].name = "__type_descriptor";
      bfields[0].btype = pdt->get_backend(gogo);
      bfields[0].location = bloc;

      Type* vt = Type::make_pointer_type(Type::make_void_type());
      bfields[1].name = "__object";
      bfields[1].btype = vt->get_backend(gogo);
      bfields[1].location = bloc;

      empty_interface_type = gogo->backend()->struct_type(bfields);
    }
  return empty_interface_type;
}

Interface_type::Bmethods_map Interface_type::bmethods_map;

// Return a pointer to the backend representation of the method table.

Btype*
Interface_type::get_backend_methods(Gogo* gogo)
{
  if (this->bmethods_ != NULL && !this->bmethods_is_placeholder_)
    return this->bmethods_;

  std::pair<Interface_type*, Bmethods_map_entry> val;
  val.first = this;
  val.second.btype = NULL;
  val.second.is_placeholder = false;
  std::pair<Bmethods_map::iterator, bool> ins =
    Interface_type::bmethods_map.insert(val);
  if (!ins.second
      && ins.first->second.btype != NULL
      && !ins.first->second.is_placeholder)
    {
      this->bmethods_ = ins.first->second.btype;
      this->bmethods_is_placeholder_ = false;
      return this->bmethods_;
    }

  Location loc = this->location();

  std::vector<Backend::Btyped_identifier>
    mfields(this->all_methods_->size() + 1);

  Type* pdt = Type::make_type_descriptor_ptr_type();
  mfields[0].name = "__type_descriptor";
  mfields[0].btype = pdt->get_backend(gogo);
  mfields[0].location = loc;

  std::string last_name = "";
  size_t i = 1;
  for (Typed_identifier_list::const_iterator p = this->all_methods_->begin();
       p != this->all_methods_->end();
       ++p, ++i)
    {
      // The type of the method in Go only includes the parameters.
      // The actual method also has a receiver, which is always a
      // pointer.  We need to add that pointer type here in order to
      // generate the correct type for the backend.
      Function_type* ft = p->type()->function_type();
      go_assert(ft->receiver() == NULL);

      const Typed_identifier_list* params = ft->parameters();
      Typed_identifier_list* mparams = new Typed_identifier_list();
      if (params != NULL)
	mparams->reserve(params->size() + 1);
      Type* vt = Type::make_pointer_type(Type::make_void_type());
      mparams->push_back(Typed_identifier("", vt, ft->location()));
      if (params != NULL)
	{
	  for (Typed_identifier_list::const_iterator pp = params->begin();
	       pp != params->end();
	       ++pp)
	    mparams->push_back(*pp);
	}

      Typed_identifier_list* mresults = (ft->results() == NULL
					 ? NULL
					 : ft->results()->copy());
      Function_type* mft = Type::make_function_type(NULL, mparams, mresults,
						    ft->location());

      mfields[i].name = Gogo::unpack_hidden_name(p->name());
      mfields[i].btype = mft->get_backend_fntype(gogo);
      mfields[i].location = loc;

      // Sanity check: the names should be sorted.
      go_assert(Gogo::unpack_hidden_name(p->name())
		> Gogo::unpack_hidden_name(last_name));
      last_name = p->name();
    }

  Btype* st = gogo->backend()->struct_type(mfields);
  Btype* ret = gogo->backend()->pointer_type(st);

  if (ins.first->second.btype != NULL
      && ins.first->second.is_placeholder)
    gogo->backend()->set_placeholder_pointer_type(ins.first->second.btype,
                                                  ret);
  this->bmethods_ = ret;
  ins.first->second.btype = ret;
  this->bmethods_is_placeholder_ = false;
  ins.first->second.is_placeholder = false;
  return ret;
}

// Return a placeholder for the pointer to the backend methods table.

Btype*
Interface_type::get_backend_methods_placeholder(Gogo* gogo)
{
  if (this->bmethods_ == NULL)
    {
      std::pair<Interface_type*, Bmethods_map_entry> val;
      val.first = this;
      val.second.btype = NULL;
      val.second.is_placeholder = false;
      std::pair<Bmethods_map::iterator, bool> ins =
        Interface_type::bmethods_map.insert(val);
      if (!ins.second && ins.first->second.btype != NULL)
        {
          this->bmethods_ = ins.first->second.btype;
          this->bmethods_is_placeholder_ = ins.first->second.is_placeholder;
          return this->bmethods_;
        }

      Location loc = this->location();
      Btype* bt = gogo->backend()->placeholder_pointer_type("", loc, false);
      this->bmethods_ = bt;
      ins.first->second.btype = bt;
      this->bmethods_is_placeholder_ = true;
      ins.first->second.is_placeholder = true;
    }
  return this->bmethods_;
}

// Return the fields of a non-empty interface type.  This is not
// declared in types.h so that types.h doesn't have to #include
// backend.h.

static void
get_backend_interface_fields(Gogo* gogo, Interface_type* type,
			     bool use_placeholder,
			     std::vector<Backend::Btyped_identifier>* bfields)
{
  Location loc = type->location();

  bfields->resize(2);

  (*bfields)[0].name = "__methods";
  (*bfields)[0].btype = (use_placeholder
			 ? type->get_backend_methods_placeholder(gogo)
			 : type->get_backend_methods(gogo));
  (*bfields)[0].location = loc;

  Type* vt = Type::make_pointer_type(Type::make_void_type());
  (*bfields)[1].name = "__object";
  (*bfields)[1].btype = vt->get_backend(gogo);
  (*bfields)[1].location = Linemap::predeclared_location();
}

// 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
// of the object itself.

Btype*
Interface_type::do_get_backend(Gogo* gogo)
{
  if (this->is_empty())
    return Interface_type::get_backend_empty_interface_type(gogo);
  else
    {
      if (this->interface_btype_ != NULL)
	return this->interface_btype_;
      this->interface_btype_ =
	gogo->backend()->placeholder_struct_type("", this->location_);
      std::vector<Backend::Btyped_identifier> bfields;
      get_backend_interface_fields(gogo, this, false, &bfields);
      if (!gogo->backend()->set_placeholder_struct_type(this->interface_btype_,
							bfields))
	this->interface_btype_ = gogo->backend()->error_type();
      return this->interface_btype_;
    }
}

// Finish the backend representation of the methods.

void
Interface_type::finish_backend_methods(Gogo* gogo)
{
  if (!this->is_empty())
    {
      const Typed_identifier_list* methods = this->methods();
      if (methods != NULL)
	{
	  for (Typed_identifier_list::const_iterator p = methods->begin();
	       p != methods->end();
	       ++p)
	    p->type()->get_backend(gogo);
	}

      // Getting the backend methods now will set the placeholder
      // pointer.
      this->get_backend_methods(gogo);
    }
}

// The type of an interface type descriptor.

Type*
Interface_type::make_interface_type_descriptor_type()
{
  static Type* ret;
  if (ret == NULL)
    {
      Type* tdt = Type::make_type_descriptor_type();
      Type* ptdt = Type::make_type_descriptor_ptr_type();

      Type* string_type = Type::lookup_string_type();
      Type* pointer_string_type = Type::make_pointer_type(string_type);

      Struct_type* sm =
	Type::make_builtin_struct_type(3,
				       "name", pointer_string_type,
				       "pkgPath", pointer_string_type,
				       "typ", ptdt);

      Type* nsm = Type::make_builtin_named_type("imethod", sm);

      Type* slice_nsm = Type::make_array_type(nsm, NULL);

      Struct_type* s = Type::make_builtin_struct_type(2,
						      "", tdt,
						      "methods", slice_nsm);

      ret = Type::make_builtin_named_type("InterfaceType", s);
    }

  return ret;
}

// Build a type descriptor for an interface type.

Expression*
Interface_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  Location bloc = Linemap::predeclared_location();

  Type* itdt = Interface_type::make_interface_type_descriptor_type();

  const Struct_field_list* ifields = itdt->struct_type()->fields();

  Expression_list* ivals = new Expression_list();
  ivals->reserve(2);

  Struct_field_list::const_iterator pif = ifields->begin();
  go_assert(pif->is_field_name("_type"));
  const int rt = RUNTIME_TYPE_KIND_INTERFACE;
  ivals->push_back(this->type_descriptor_constructor(gogo, rt, name, NULL,
						     true));

  ++pif;
  go_assert(pif->is_field_name("methods"));

  Expression_list* methods = new Expression_list();
  if (this->all_methods_ != NULL)
    {
      Type* elemtype = pif->type()->array_type()->element_type();

      methods->reserve(this->all_methods_->size());
      for (Typed_identifier_list::const_iterator pm =
	     this->all_methods_->begin();
	   pm != this->all_methods_->end();
	   ++pm)
	{
	  const Struct_field_list* mfields = elemtype->struct_type()->fields();

	  Expression_list* mvals = new Expression_list();
	  mvals->reserve(3);

	  Struct_field_list::const_iterator pmf = mfields->begin();
	  go_assert(pmf->is_field_name("name"));
	  std::string s = Gogo::unpack_hidden_name(pm->name());
	  Expression* e = Expression::make_string(s, bloc);
	  mvals->push_back(Expression::make_unary(OPERATOR_AND, e, bloc));

	  ++pmf;
	  go_assert(pmf->is_field_name("pkgPath"));
	  if (!Gogo::is_hidden_name(pm->name()))
	    mvals->push_back(Expression::make_nil(bloc));
	  else
	    {
	      s = Gogo::hidden_name_pkgpath(pm->name());
	      e = Expression::make_string(s, bloc);
	      mvals->push_back(Expression::make_unary(OPERATOR_AND, e, bloc));
	    }

	  ++pmf;
	  go_assert(pmf->is_field_name("typ"));
	  mvals->push_back(Expression::make_type_descriptor(pm->type(), bloc));

	  ++pmf;
	  go_assert(pmf == mfields->end());

	  e = Expression::make_struct_composite_literal(elemtype, mvals,
							bloc);
	  methods->push_back(e);
	}
    }

  ivals->push_back(Expression::make_slice_composite_literal(pif->type(),
							    methods, bloc));

  ++pif;
  go_assert(pif == ifields->end());

  return Expression::make_struct_composite_literal(itdt, ivals, bloc);
}

// Reflection string.

void
Interface_type::do_reflection(Gogo* gogo, std::string* ret) const
{
  ret->append("interface {");
  const Typed_identifier_list* methods = this->parse_methods_;
  if (methods != NULL)
    {
      ret->push_back(' ');
      for (Typed_identifier_list::const_iterator p = methods->begin();
	   p != methods->end();
	   ++p)
	{
	  if (p != methods->begin())
	    ret->append("; ");
	  if (p->name().empty())
	    this->append_reflection(p->type(), gogo, ret);
	  else
	    {
	      if (!Gogo::is_hidden_name(p->name()))
		ret->append(p->name());
	      else if (gogo->pkgpath_from_option())
		ret->append(p->name().substr(1));
	      else
		{
		  // If no -fgo-pkgpath option, backward compatibility
		  // for how this used to work before -fgo-pkgpath was
		  // introduced.
		  std::string pkgpath = Gogo::hidden_name_pkgpath(p->name());
		  ret->append(pkgpath.substr(pkgpath.find('.') + 1));
		  ret->push_back('.');
		  ret->append(Gogo::unpack_hidden_name(p->name()));
		}
	      std::string sub = p->type()->reflection(gogo);
	      go_assert(sub.compare(0, 4, "func") == 0);
	      sub = sub.substr(4);
	      ret->append(sub);
	    }
	}
      ret->push_back(' ');
    }
  ret->append("}");
}

// Export.

void
Interface_type::do_export(Export* exp) const
{
  exp->write_c_string("interface { ");

  const Typed_identifier_list* methods = this->parse_methods_;
  if (methods != NULL)
    {
      for (Typed_identifier_list::const_iterator pm = methods->begin();
	   pm != methods->end();
	   ++pm)
	{
	  if (pm->name().empty())
	    {
	      exp->write_c_string("? ");
	      exp->write_type(pm->type());
	    }
	  else
	    {
	      exp->write_string(pm->name());
	      exp->write_c_string(" (");

	      const Function_type* fntype = pm->type()->function_type();

	      bool first = true;
	      const Typed_identifier_list* parameters = fntype->parameters();
	      if (parameters != NULL)
		{
		  bool is_varargs = fntype->is_varargs();
		  for (Typed_identifier_list::const_iterator pp =
			 parameters->begin();
		       pp != parameters->end();
		       ++pp)
		    {
		      if (first)
			first = false;
		      else
			exp->write_c_string(", ");
		      exp->write_name(pp->name());
		      exp->write_c_string(" ");
		      if (!is_varargs || pp + 1 != parameters->end())
			exp->write_type(pp->type());
		      else
			{
			  exp->write_c_string("...");
			  Type *pptype = pp->type();
			  exp->write_type(pptype->array_type()->element_type());
			}
		    }
		}

	      exp->write_c_string(")");

	      const Typed_identifier_list* results = fntype->results();
	      if (results != NULL)
		{
		  exp->write_c_string(" ");
		  if (results->size() == 1 && results->begin()->name().empty())
		    exp->write_type(results->begin()->type());
		  else
		    {
		      first = true;
		      exp->write_c_string("(");
		      for (Typed_identifier_list::const_iterator p =
			     results->begin();
			   p != results->end();
			   ++p)
			{
			  if (first)
			    first = false;
			  else
			    exp->write_c_string(", ");
			  exp->write_name(p->name());
			  exp->write_c_string(" ");
			  exp->write_type(p->type());
			}
		      exp->write_c_string(")");
		    }
		}
	    }

	  exp->write_c_string("; ");
	}
    }

  exp->write_c_string("}");
}

// Import an interface type.

Interface_type*
Interface_type::do_import(Import* imp)
{
  imp->require_c_string("interface { ");

  Typed_identifier_list* methods = new Typed_identifier_list;
  while (imp->peek_char() != '}')
    {
      std::string name = imp->read_identifier();

      if (name == "?")
	{
	  imp->require_c_string(" ");
	  Type* t = imp->read_type();
	  methods->push_back(Typed_identifier("", t, imp->location()));
	  imp->require_c_string("; ");
	  continue;
	}

      imp->require_c_string(" (");

      Typed_identifier_list* parameters;
      bool is_varargs = false;
      if (imp->peek_char() == ')')
	parameters = NULL;
      else
	{
	  parameters = new Typed_identifier_list;
	  while (true)
	    {
	      std::string name = imp->read_name();
	      imp->require_c_string(" ");

	      if (imp->match_c_string("..."))
		{
		  imp->advance(3);
		  is_varargs = true;
		}

	      Type* ptype = imp->read_type();
	      if (is_varargs)
		ptype = Type::make_array_type(ptype, NULL);
	      parameters->push_back(Typed_identifier(name, ptype,
						     imp->location()));
	      if (imp->peek_char() != ',')
		break;
	      go_assert(!is_varargs);
	      imp->require_c_string(", ");
	    }
	}
      imp->require_c_string(")");

      Typed_identifier_list* results;
      if (imp->peek_char() != ' ')
	results = NULL;
      else
	{
	  results = new Typed_identifier_list;
	  imp->advance(1);
	  if (imp->peek_char() != '(')
	    {
	      Type* rtype = imp->read_type();
	      results->push_back(Typed_identifier("", rtype, imp->location()));
	    }
	  else
	    {
	      imp->advance(1);
	      while (true)
		{
		  std::string name = imp->read_name();
		  imp->require_c_string(" ");
		  Type* rtype = imp->read_type();
		  results->push_back(Typed_identifier(name, rtype,
						      imp->location()));
		  if (imp->peek_char() != ',')
		    break;
		  imp->require_c_string(", ");
		}
	      imp->require_c_string(")");
	    }
	}

      Function_type* fntype = Type::make_function_type(NULL, parameters,
						       results,
						       imp->location());
      if (is_varargs)
	fntype->set_is_varargs();
      methods->push_back(Typed_identifier(name, fntype, imp->location()));

      imp->require_c_string("; ");
    }

  imp->require_c_string("}");

  if (methods->empty())
    {
      delete methods;
      methods = NULL;
    }

  Interface_type* ret = Type::make_interface_type(methods, imp->location());
  ret->package_ = imp->package();
  return ret;
}

// Make an interface type.

Interface_type*
Type::make_interface_type(Typed_identifier_list* methods,
			  Location location)
{
  return new Interface_type(methods, location);
}

// Make an empty interface type.

Interface_type*
Type::make_empty_interface_type(Location location)
{
  Interface_type* ret = new Interface_type(NULL, location);
  ret->finalize_methods();
  return ret;
}

// Class Method.

// Bind a method to an object.

Expression*
Method::bind_method(Expression* expr, Location location) const
{
  if (this->stub_ == NULL)
    {
      // When there is no stub object, the binding is determined by
      // the child class.
      return this->do_bind_method(expr, location);
    }
  return Expression::make_bound_method(expr, this, this->stub_, location);
}

// Return the named object associated with a method.  This may only be
// called after methods are finalized.

Named_object*
Method::named_object() const
{
  if (this->stub_ != NULL)
    return this->stub_;
  return this->do_named_object();
}

// Class Named_method.

// The type of the method.

Function_type*
Named_method::do_type() const
{
  if (this->named_object_->is_function())
    return this->named_object_->func_value()->type();
  else if (this->named_object_->is_function_declaration())
    return this->named_object_->func_declaration_value()->type();
  else
    go_unreachable();
}

// Return the location of the method receiver.

Location
Named_method::do_receiver_location() const
{
  return this->do_type()->receiver()->location();
}

// Bind a method to an object.

Expression*
Named_method::do_bind_method(Expression* expr, Location location) const
{
  Named_object* no = this->named_object_;
  Bound_method_expression* bme = Expression::make_bound_method(expr, this,
							       no, location);
  // If this is not a local method, and it does not use a stub, then
  // the real method expects a different type.  We need to cast the
  // first argument.
  if (this->depth() > 0 && !this->needs_stub_method())
    {
      Function_type* ftype = this->do_type();
      go_assert(ftype->is_method());
      Type* frtype = ftype->receiver()->type();
      bme->set_first_argument_type(frtype);
    }
  return bme;
}

// Return whether this method should not participate in interfaces.

bool
Named_method::do_nointerface() const
{
  Named_object* no = this->named_object_;
  if (no->is_function())
    return no->func_value()->nointerface();
  else if (no->is_function_declaration())
    return no->func_declaration_value()->nointerface();
  else
    go_unreachable();
}

// Class Interface_method.

// Bind a method to an object.

Expression*
Interface_method::do_bind_method(Expression* expr,
				 Location location) const
{
  return Expression::make_interface_field_reference(expr, this->name_,
						    location);
}

// Class Methods.

// Insert a new method.  Return true if it was inserted, false
// otherwise.

bool
Methods::insert(const std::string& name, Method* m)
{
  std::pair<Method_map::iterator, bool> ins =
    this->methods_.insert(std::make_pair(name, m));
  if (ins.second)
    return true;
  else
    {
      Method* old_method = ins.first->second;
      if (m->depth() < old_method->depth())
	{
	  delete old_method;
	  ins.first->second = m;
	  return true;
	}
      else
	{
	  if (m->depth() == old_method->depth())
	    old_method->set_is_ambiguous();
	  return false;
	}
    }
}

// Return the number of unambiguous methods.

size_t
Methods::count() const
{
  size_t ret = 0;
  for (Method_map::const_iterator p = this->methods_.begin();
       p != this->methods_.end();
       ++p)
    if (!p->second->is_ambiguous())
      ++ret;
  return ret;
}

// Class Named_type.

// Return the name of the type.

const std::string&
Named_type::name() const
{
  return this->named_object_->name();
}

// Return the name of the type to use in an error message.

std::string
Named_type::message_name() const
{
  return this->named_object_->message_name();
}

// Return the base type for this type.  We have to be careful about
// circular type definitions, which are invalid but may be seen here.

Type*
Named_type::named_base()
{
  if (this->seen_)
    return this;
  this->seen_ = true;
  Type* ret = this->type_->base();
  this->seen_ = false;
  return ret;
}

const Type*
Named_type::named_base() const
{
  if (this->seen_)
    return this;
  this->seen_ = true;
  const Type* ret = this->type_->base();
  this->seen_ = false;
  return ret;
}

// Return whether this is an error type.  We have to be careful about
// circular type definitions, which are invalid but may be seen here.

bool
Named_type::is_named_error_type() const
{
  if (this->seen_)
    return false;
  this->seen_ = true;
  bool ret = this->type_->is_error_type();
  this->seen_ = false;
  return ret;
}

// Whether this type is comparable.  We have to be careful about
// circular type definitions.

bool
Named_type::named_type_is_comparable(std::string* reason) const
{
  if (this->seen_)
    return false;
  this->seen_ = true;
  bool ret = Type::are_compatible_for_comparison(true, this->type_,
						 this->type_, reason);
  this->seen_ = false;
  return ret;
}

// Add a method to this type.

Named_object*
Named_type::add_method(const std::string& name, Function* function)
{
  go_assert(!this->is_alias_);
  if (this->local_methods_ == NULL)
    this->local_methods_ = new Bindings(NULL);
  return this->local_methods_->add_function(name, NULL, function);
}

// Add a method declaration to this type.

Named_object*
Named_type::add_method_declaration(const std::string& name, Package* package,
				   Function_type* type,
				   Location location)
{
  go_assert(!this->is_alias_);
  if (this->local_methods_ == NULL)
    this->local_methods_ = new Bindings(NULL);
  return this->local_methods_->add_function_declaration(name, package, type,
							location);
}

// Add an existing method to this type.

void
Named_type::add_existing_method(Named_object* no)
{
  go_assert(!this->is_alias_);
  if (this->local_methods_ == NULL)
    this->local_methods_ = new Bindings(NULL);
  this->local_methods_->add_named_object(no);
}

// Look for a local method NAME, and returns its named object, or NULL
// if not there.

Named_object*
Named_type::find_local_method(const std::string& name) const
{
  if (this->is_error_)
    return NULL;
  if (this->is_alias_)
    {
      Named_type* nt = this->type_->named_type();
      if (nt != NULL)
	{
	  if (this->seen_alias_)
	    return NULL;
	  this->seen_alias_ = true;
	  Named_object* ret = nt->find_local_method(name);
	  this->seen_alias_ = false;
	  return ret;
	}
      return NULL;
    }
  if (this->local_methods_ == NULL)
    return NULL;
  return this->local_methods_->lookup(name);
}

// Return the list of local methods.

const Bindings*
Named_type::local_methods() const
{
  if (this->is_error_)
    return NULL;
  if (this->is_alias_)
    {
      Named_type* nt = this->type_->named_type();
      if (nt != NULL)
	{
	  if (this->seen_alias_)
	    return NULL;
	  this->seen_alias_ = true;
	  const Bindings* ret = nt->local_methods();
	  this->seen_alias_ = false;
	  return ret;
	}
      return NULL;
    }
  return this->local_methods_;
}

// Return whether NAME is an unexported field or method, for better
// error reporting.

bool
Named_type::is_unexported_local_method(Gogo* gogo,
				       const std::string& name) const
{
  if (this->is_error_)
    return false;
  if (this->is_alias_)
    {
      Named_type* nt = this->type_->named_type();
      if (nt != NULL)
	{
	  if (this->seen_alias_)
	    return false;
	  this->seen_alias_ = true;
	  bool ret = nt->is_unexported_local_method(gogo, name);
	  this->seen_alias_ = false;
	  return ret;
	}
      return false;
    }
  Bindings* methods = this->local_methods_;
  if (methods != NULL)
    {
      for (Bindings::const_declarations_iterator p =
	     methods->begin_declarations();
	   p != methods->end_declarations();
	   ++p)
	{
	  if (Gogo::is_hidden_name(p->first)
	      && name == Gogo::unpack_hidden_name(p->first)
	      && gogo->pack_hidden_name(name, false) != p->first)
	    return true;
	}
    }
  return false;
}

// Build the complete list of methods for this type, which means
// recursively including all methods for anonymous fields.  Create all
// stub methods.

void
Named_type::finalize_methods(Gogo* gogo)
{
  if (this->is_alias_)
    return;
  if (this->all_methods_ != NULL)
    return;

  if (this->local_methods_ != NULL
      && (this->points_to() != NULL || this->interface_type() != NULL))
    {
      const Bindings* lm = this->local_methods_;
      for (Bindings::const_declarations_iterator p = lm->begin_declarations();
	   p != lm->end_declarations();
	   ++p)
	go_error_at(p->second->location(),
		    "invalid pointer or interface receiver type");
      delete this->local_methods_;
      this->local_methods_ = NULL;
      return;
    }

  Type::finalize_methods(gogo, this, this->location_, &this->all_methods_);
}

// Return whether this type has any methods.

bool
Named_type::has_any_methods() const
{
  if (this->is_error_)
    return false;
  if (this->is_alias_)
    {
      if (this->type_->named_type() != NULL)
	{
	  if (this->seen_alias_)
	    return false;
	  this->seen_alias_ = true;
	  bool ret = this->type_->named_type()->has_any_methods();
	  this->seen_alias_ = false;
	  return ret;
	}
      if (this->type_->struct_type() != NULL)
	return this->type_->struct_type()->has_any_methods();
      return false;
    }
  return this->all_methods_ != NULL;
}

// Return the methods for this type.

const Methods*
Named_type::methods() const
{
  if (this->is_error_)
    return NULL;
  if (this->is_alias_)
    {
      if (this->type_->named_type() != NULL)
	{
	  if (this->seen_alias_)
	    return NULL;
	  this->seen_alias_ = true;
	  const Methods* ret = this->type_->named_type()->methods();
	  this->seen_alias_ = false;
	  return ret;
	}
      if (this->type_->struct_type() != NULL)
	return this->type_->struct_type()->methods();
      return NULL;
    }
  return this->all_methods_;
}

// Return the method NAME, or NULL if there isn't one or if it is
// ambiguous.  Set *IS_AMBIGUOUS if the method exists but is
// ambiguous.

Method*
Named_type::method_function(const std::string& name, bool* is_ambiguous) const
{
  if (this->is_error_)
    return NULL;
  if (this->is_alias_)
    {
      if (is_ambiguous != NULL)
	*is_ambiguous = false;
      if (this->type_->named_type() != NULL)
	{
	  if (this->seen_alias_)
	    return NULL;
	  this->seen_alias_ = true;
	  Named_type* nt = this->type_->named_type();
	  Method* ret = nt->method_function(name, is_ambiguous);
	  this->seen_alias_ = false;
	  return ret;
	}
      if (this->type_->struct_type() != NULL)
	return this->type_->struct_type()->method_function(name, is_ambiguous);
      return NULL;
    }
  return Type::method_function(this->all_methods_, name, is_ambiguous);
}

// Return a pointer to the interface method table for this type for
// the interface INTERFACE.  IS_POINTER is true if this is for a
// pointer to THIS.

Expression*
Named_type::interface_method_table(Interface_type* interface, bool is_pointer)
{
  if (this->is_error_)
    return Expression::make_error(this->location_);
  if (this->is_alias_)
    {
      if (this->type_->named_type() != NULL)
	{
	  if (this->seen_alias_)
	    return Expression::make_error(this->location_);
	  this->seen_alias_ = true;
	  Named_type* nt = this->type_->named_type();
	  Expression* ret = nt->interface_method_table(interface, is_pointer);
	  this->seen_alias_ = false;
	  return ret;
	}
      if (this->type_->struct_type() != NULL)
	return this->type_->struct_type()->interface_method_table(interface,
								  is_pointer);
      go_unreachable();
    }
  return Type::interface_method_table(this, interface, is_pointer,
                                      &this->interface_method_tables_,
                                      &this->pointer_interface_method_tables_);
}

// Look for a use of a complete type within another type.  This is
// used to check that we don't try to use a type within itself.

class Find_type_use : public Traverse
{
 public:
  Find_type_use(Named_type* find_type)
    : Traverse(traverse_types),
      find_type_(find_type), found_(false)
  { }

  // Whether we found the type.
  bool
  found() const
  { return this->found_; }

 protected:
  int
  type(Type*);

 private:
  // The type we are looking for.
  Named_type* find_type_;
  // Whether we found the type.
  bool found_;
};

// Check for FIND_TYPE in TYPE.

int
Find_type_use::type(Type* type)
{
  if (type->named_type() != NULL && this->find_type_ == type->named_type())
    {
      this->found_ = true;
      return TRAVERSE_EXIT;
    }

  // It's OK if we see a reference to the type in any type which is
  // essentially a pointer: a pointer, a slice, a function, a map, or
  // a channel.
  if (type->points_to() != NULL
      || type->is_slice_type()
      || type->function_type() != NULL
      || type->map_type() != NULL
      || type->channel_type() != NULL)
    return TRAVERSE_SKIP_COMPONENTS;

  // For an interface, a reference to the type in a method type should
  // be ignored, but we have to consider direct inheritance.  When
  // this is called, there may be cases of direct inheritance
  // represented as a method with no name.
  if (type->interface_type() != NULL)
    {
      const Typed_identifier_list* methods = type->interface_type()->methods();
      if (methods != NULL)
	{
	  for (Typed_identifier_list::const_iterator p = methods->begin();
	       p != methods->end();
	       ++p)
	    {
	      if (p->name().empty())
		{
		  if (Type::traverse(p->type(), this) == TRAVERSE_EXIT)
		    return TRAVERSE_EXIT;
		}
	    }
	}
      return TRAVERSE_SKIP_COMPONENTS;
    }

  // Otherwise, FIND_TYPE_ depends on TYPE, in the sense that we need
  // to convert TYPE to the backend representation before we convert
  // FIND_TYPE_.
  if (type->named_type() != NULL)
    {
      switch (type->base()->classification())
	{
	case Type::TYPE_ERROR:
	case Type::TYPE_BOOLEAN:
	case Type::TYPE_INTEGER:
	case Type::TYPE_FLOAT:
	case Type::TYPE_COMPLEX:
	case Type::TYPE_STRING:
	case Type::TYPE_NIL:
	  break;

	case Type::TYPE_ARRAY:
	case Type::TYPE_STRUCT:
	  this->find_type_->add_dependency(type->named_type());
	  break;

	case Type::TYPE_NAMED:
	case Type::TYPE_FORWARD:
	  go_assert(saw_errors());
	  break;

	case Type::TYPE_VOID:
	case Type::TYPE_SINK:
	case Type::TYPE_FUNCTION:
	case Type::TYPE_POINTER:
	case Type::TYPE_CALL_MULTIPLE_RESULT:
	case Type::TYPE_MAP:
	case Type::TYPE_CHANNEL:
	case Type::TYPE_INTERFACE:
	default:
	  go_unreachable();
	}
    }

  return TRAVERSE_CONTINUE;
}

// Look for a circular reference of an alias.

class Find_alias : public Traverse
{
 public:
  Find_alias(Named_type* find_type)
    : Traverse(traverse_types),
      find_type_(find_type), found_(false)
  { }

  // Whether we found the type.
  bool
  found() const
  { return this->found_; }

 protected:
  int
  type(Type*);

 private:
  // The type we are looking for.
  Named_type* find_type_;
  // Whether we found the type.
  bool found_;
};

int
Find_alias::type(Type* type)
{
  Named_type* nt = type->named_type();
  if (nt != NULL)
    {
      if (nt == this->find_type_)
	{
	  this->found_ = true;
	  return TRAVERSE_EXIT;
	}

      // We started from `type T1 = T2`, where T1 is find_type_ and T2
      // is, perhaps indirectly, the parameter TYPE.  If TYPE is not
      // an alias itself, it's OK if whatever T2 is defined as refers
      // to T1.
      if (!nt->is_alias())
	return TRAVERSE_SKIP_COMPONENTS;
    }

  return TRAVERSE_CONTINUE;
}

// Verify that a named type does not refer to itself.

bool
Named_type::do_verify()
{
  if (this->is_verified_)
    return true;
  this->is_verified_ = true;

  if (this->is_error_)
    return false;

  if (this->is_alias_)
    {
      Find_alias find(this);
      Type::traverse(this->type_, &find);
      if (find.found())
	{
	  go_error_at(this->location_, "invalid recursive alias %qs",
		      this->message_name().c_str());
	  this->is_error_ = true;
	  return false;
	}
    }

  Find_type_use find(this);
  Type::traverse(this->type_, &find);
  if (find.found())
    {
      go_error_at(this->location_, "invalid recursive type %qs",
		  this->message_name().c_str());
      this->is_error_ = true;
      return false;
    }

  // Check whether any of the local methods overloads an existing
  // struct field or interface method.  We don't need to check the
  // list of methods against itself: that is handled by the Bindings
  // code.
  if (this->local_methods_ != NULL)
    {
      Struct_type* st = this->type_->struct_type();
      if (st != NULL)
	{
	  for (Bindings::const_declarations_iterator p =
		 this->local_methods_->begin_declarations();
	       p != this->local_methods_->end_declarations();
	       ++p)
	    {
	      const std::string& name(p->first);
	      if (st != NULL && st->find_local_field(name, NULL) != NULL)
		{
		  go_error_at(p->second->location(),
			      "method %qs redeclares struct field name",
			      Gogo::message_name(name).c_str());
		}
	    }
	}
    }

  return true;
}

// Return whether this type is or contains a pointer.

bool
Named_type::do_has_pointer() const
{
  if (this->seen_)
    return false;
  this->seen_ = true;
  bool ret = this->type_->has_pointer();
  this->seen_ = false;
  return ret;
}

// Return whether comparisons for this type can use the identity
// function.

bool
Named_type::do_compare_is_identity(Gogo* gogo)
{
  // We don't use this->seen_ here because compare_is_identity may
  // call base() later, and that will mess up if seen_ is set here.
  if (this->seen_in_compare_is_identity_)
    return false;
  this->seen_in_compare_is_identity_ = true;
  bool ret = this->type_->compare_is_identity(gogo);
  this->seen_in_compare_is_identity_ = false;
  return ret;
}

// Return whether this type is reflexive--whether it is always equal
// to itself.

bool
Named_type::do_is_reflexive()
{
  if (this->seen_in_compare_is_identity_)
    return false;
  this->seen_in_compare_is_identity_ = true;
  bool ret = this->type_->is_reflexive();
  this->seen_in_compare_is_identity_ = false;
  return ret;
}

// Return whether this type needs a key update when used as a map key.

bool
Named_type::do_needs_key_update()
{
  if (this->seen_in_compare_is_identity_)
    return true;
  this->seen_in_compare_is_identity_ = true;
  bool ret = this->type_->needs_key_update();
  this->seen_in_compare_is_identity_ = false;
  return ret;
}

// Return a hash code.  This is used for method lookup.  We simply
// hash on the name itself.

unsigned int
Named_type::do_hash_for_method(Gogo* gogo, int) const
{
  if (this->is_error_)
    return 0;

  // Aliases are handled in Type::hash_for_method.
  go_assert(!this->is_alias_);

  const std::string& name(this->named_object()->name());
  unsigned int ret = Type::hash_string(name, 0);

  // GOGO will be NULL here when called from Type_hash_identical.
  // That is OK because that is only used for internal hash tables
  // where we are going to be comparing named types for equality.  In
  // other cases, which are cases where the runtime is going to
  // compare hash codes to see if the types are the same, we need to
  // include the pkgpath in the hash.
  if (gogo != NULL && !Gogo::is_hidden_name(name) && !this->is_builtin())
    {
      const Package* package = this->named_object()->package();
      if (package == NULL)
	ret = Type::hash_string(gogo->pkgpath(), ret);
      else
	ret = Type::hash_string(package->pkgpath(), ret);
    }

  return ret;
}

// Convert a named type to the backend representation.  In order to
// get dependencies right, we fill in a dummy structure for this type,
// then convert all the dependencies, then complete this type.  When
// this function is complete, the size of the type is known.

void
Named_type::convert(Gogo* gogo)
{
  if (this->is_error_ || this->is_converted_)
    return;

  this->create_placeholder(gogo);

  // If we are called to turn unsafe.Sizeof into a constant, we may
  // not have verified the type yet.  We have to make sure it is
  // verified, since that sets the list of dependencies.
  this->verify();

  // Convert all the dependencies.  If they refer indirectly back to
  // 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();
       ++p)
    (*p)->convert(gogo);

  // Complete this type.
  Btype* bt = this->named_btype_;
  Type* base = this->type_->base();
  switch (base->classification())
    {
    case TYPE_VOID:
    case TYPE_BOOLEAN:
    case TYPE_INTEGER:
    case TYPE_FLOAT:
    case TYPE_COMPLEX:
    case TYPE_STRING:
    case TYPE_NIL:
      break;

    case TYPE_MAP:
    case TYPE_CHANNEL:
      break;

    case TYPE_FUNCTION:
    case TYPE_POINTER:
      // The size of these types is already correct.  We don't worry
      // about filling them in until later, when we also track
      // circular references.
      break;

    case TYPE_STRUCT:
      {
	std::vector<Backend::Btyped_identifier> bfields;
	get_backend_struct_fields(gogo, base->struct_type()->fields(),
				  true, &bfields);
	if (!gogo->backend()->set_placeholder_struct_type(bt, bfields))
	  bt = gogo->backend()->error_type();
      }
      break;

    case TYPE_ARRAY:
      // Slice types were completed in create_placeholder.
      if (!base->is_slice_type())
	{
	  Btype* bet = base->array_type()->get_backend_element(gogo, true);
	  Bexpression* blen = base->array_type()->get_backend_length(gogo);
	  if (!gogo->backend()->set_placeholder_array_type(bt, bet, blen))
	    bt = gogo->backend()->error_type();
	}
      break;

    case TYPE_INTERFACE:
      // Interface types were completed in create_placeholder.
      break;

    case TYPE_ERROR:
      return;

    default:
    case TYPE_SINK:
    case TYPE_CALL_MULTIPLE_RESULT:
    case TYPE_NAMED:
    case TYPE_FORWARD:
      go_unreachable();
    }

  this->named_btype_ = bt;
  this->is_converted_ = true;
  this->is_placeholder_ = false;
}

// Create the placeholder for a named type.  This is the first step in
// converting to the backend representation.

void
Named_type::create_placeholder(Gogo* gogo)
{
  if (this->is_error_)
    this->named_btype_ = gogo->backend()->error_type();

  if (this->named_btype_ != NULL)
    return;

  // Create the structure for this type.  Note that because we call
  // base() here, we don't attempt to represent a named type defined
  // as another named type.  Instead both named types will point to
  // different base representations.
  Type* base = this->type_->base();
  Btype* bt;
  bool set_name = true;
  switch (base->classification())
    {
    case TYPE_ERROR:
      this->is_error_ = true;
      this->named_btype_ = gogo->backend()->error_type();
      return;

    case TYPE_VOID:
    case TYPE_BOOLEAN:
    case TYPE_INTEGER:
    case TYPE_FLOAT:
    case TYPE_COMPLEX:
    case TYPE_STRING:
    case TYPE_NIL:
      // These are simple basic types, we can just create them
      // directly.
      bt = Type::get_named_base_btype(gogo, base);
      break;

    case TYPE_MAP:
    case TYPE_CHANNEL:
      // All maps and channels have the same backend representation.
      bt = Type::get_named_base_btype(gogo, base);
      break;

    case TYPE_FUNCTION:
    case TYPE_POINTER:
      {
	bool for_function = base->classification() == TYPE_FUNCTION;
	bt = gogo->backend()->placeholder_pointer_type(this->name(),
						       this->location_,
						       for_function);
	set_name = false;
      }
      break;

    case TYPE_STRUCT:
      bt = gogo->backend()->placeholder_struct_type(this->name(),
						    this->location_);
      this->is_placeholder_ = true;
      set_name = false;
      break;

    case TYPE_ARRAY:
      if (base->is_slice_type())
	bt = gogo->backend()->placeholder_struct_type(this->name(),
						      this->location_);
      else
	{
	  bt = gogo->backend()->placeholder_array_type(this->name(),
						       this->location_);
	  this->is_placeholder_ = true;
	}
      set_name = false;
      break;

    case TYPE_INTERFACE:
      if (base->interface_type()->is_empty())
	bt = Interface_type::get_backend_empty_interface_type(gogo);
      else
	{
	  bt = gogo->backend()->placeholder_struct_type(this->name(),
							this->location_);
	  set_name = false;
	}
      break;

    default:
    case TYPE_SINK:
    case TYPE_CALL_MULTIPLE_RESULT:
    case TYPE_NAMED:
    case TYPE_FORWARD:
      go_unreachable();
    }

  if (set_name)
    bt = gogo->backend()->named_type(this->name(), bt, this->location_);

  this->named_btype_ = bt;

  if (base->is_slice_type())
    {
      // We do not record slices as dependencies of other types,
      // because we can fill them in completely here with the final
      // size.
      std::vector<Backend::Btyped_identifier> bfields;
      get_backend_slice_fields(gogo, base->array_type(), true, &bfields);
      if (!gogo->backend()->set_placeholder_struct_type(bt, bfields))
	this->named_btype_ = gogo->backend()->error_type();
    }
  else if (base->interface_type() != NULL
	   && !base->interface_type()->is_empty())
    {
      // We do not record interfaces as dependencies of other types,
      // because we can fill them in completely here with the final
      // size.
      std::vector<Backend::Btyped_identifier> bfields;
      get_backend_interface_fields(gogo, base->interface_type(), true,
				   &bfields);
      if (!gogo->backend()->set_placeholder_struct_type(bt, bfields))
	this->named_btype_ = gogo->backend()->error_type();
    }
}

// Get the backend representation for a named type.

Btype*
Named_type::do_get_backend(Gogo* gogo)
{
  if (this->is_error_)
    return gogo->backend()->error_type();

  Btype* bt = this->named_btype_;

  if (!gogo->named_types_are_converted())
    {
      // We have not completed converting named types.  NAMED_BTYPE_
      // is a placeholder and we shouldn't do anything further.
      if (bt != NULL)
	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
      // converting types.
      this->create_placeholder(gogo);
      bt = this->named_btype_;
      go_assert(bt != NULL);
      return bt;
    }

  // We are not converting types.  This should only be called if the
  // type has already been converted.
  if (!this->is_converted_)
    {
      go_assert(saw_errors());
      return gogo->backend()->error_type();
    }

  go_assert(bt != NULL);

  // Complete the backend representation.
  Type* base = this->type_->base();
  Btype* bt1;
  switch (base->classification())
    {
    case TYPE_ERROR:
      return gogo->backend()->error_type();

    case TYPE_VOID:
    case TYPE_BOOLEAN:
    case TYPE_INTEGER:
    case TYPE_FLOAT:
    case TYPE_COMPLEX:
    case TYPE_STRING:
    case TYPE_NIL:
    case TYPE_MAP:
    case TYPE_CHANNEL:
      return bt;

    case TYPE_STRUCT:
      if (!this->seen_in_get_backend_)
	{
	  this->seen_in_get_backend_ = true;
	  base->struct_type()->finish_backend_fields(gogo);
	  this->seen_in_get_backend_ = false;
	}
      return bt;

    case TYPE_ARRAY:
      if (!this->seen_in_get_backend_)
	{
	  this->seen_in_get_backend_ = true;
	  base->array_type()->finish_backend_element(gogo);
	  this->seen_in_get_backend_ = false;
	}
      return bt;

    case TYPE_INTERFACE:
      if (!this->seen_in_get_backend_)
	{
	  this->seen_in_get_backend_ = true;
	  base->interface_type()->finish_backend_methods(gogo);
	  this->seen_in_get_backend_ = false;
	}
      return bt;

    case TYPE_FUNCTION:
      // Don't build a circular data structure.  GENERIC can't handle
      // it.
      if (this->seen_in_get_backend_)
        return gogo->backend()->circular_pointer_type(bt, true);
      this->seen_in_get_backend_ = true;
      bt1 = Type::get_named_base_btype(gogo, base);
      this->seen_in_get_backend_ = false;
      if (!gogo->backend()->set_placeholder_pointer_type(bt, bt1))
	bt = gogo->backend()->error_type();
      return bt;

    case TYPE_POINTER:
      // Don't build a circular data structure. GENERIC can't handle
      // it.
      if (this->seen_in_get_backend_)
        return gogo->backend()->circular_pointer_type(bt, false);
      this->seen_in_get_backend_ = true;
      bt1 = Type::get_named_base_btype(gogo, base);
      this->seen_in_get_backend_ = false;
      if (!gogo->backend()->set_placeholder_pointer_type(bt, bt1))
	bt = gogo->backend()->error_type();
      return bt;

    default:
    case TYPE_SINK:
    case TYPE_CALL_MULTIPLE_RESULT:
    case TYPE_NAMED:
    case TYPE_FORWARD:
      go_unreachable();
    }

  go_unreachable();
}

// Build a type descriptor for a named type.

Expression*
Named_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  if (this->is_error_)
    return Expression::make_error(this->location_);
  if (name == NULL && this->is_alias_)
    {
      if (this->seen_alias_)
	return Expression::make_error(this->location_);
      this->seen_alias_ = true;
      Expression* ret = this->type_->type_descriptor(gogo, NULL);
      this->seen_alias_ = false;
      return ret;
    }

  // If NAME is not NULL, then we don't really want the type
  // descriptor for this type; we want the descriptor for the
  // underlying type, giving it the name NAME.
  return this->named_type_descriptor(gogo, this->type_,
				     name == NULL ? this : name);
}

// Add to the reflection string.  This is used mostly for the name of
// the type used in a type descriptor, not for actual reflection
// strings.

void
Named_type::do_reflection(Gogo* gogo, std::string* ret) const
{
  this->append_reflection_type_name(gogo, false, ret);
}

// Add to the reflection string.  For an alias we normally use the
// real name, but if USE_ALIAS is true we use the alias name itself.

void
Named_type::append_reflection_type_name(Gogo* gogo, bool use_alias,
					std::string* ret) const
{
  if (this->is_error_)
    return;
  if (this->is_alias_ && !use_alias)
    {
      if (this->seen_alias_)
	return;
      this->seen_alias_ = true;
      this->append_reflection(this->type_, gogo, ret);
      this->seen_alias_ = false;
      return;
    }
  if (!this->is_builtin())
    {
      // When -fgo-pkgpath or -fgo-prefix is specified, we use it to
      // make a unique reflection string, so that the type
      // canonicalization in the reflect package will work.  In order
      // to be compatible with the gc compiler, we put tabs into the
      // package path, so that the reflect methods can discard it.
      const Package* package = this->named_object_->package();
      ret->push_back('\t');
      ret->append(package != NULL
		  ? package->pkgpath_symbol()
		  : gogo->pkgpath_symbol());
      ret->push_back('\t');
      ret->append(package != NULL
		  ? package->package_name()
		  : gogo->package_name());
      ret->push_back('.');
    }
  if (this->in_function_ != NULL)
    {
      ret->push_back('\t');
      const Typed_identifier* rcvr =
	this->in_function_->func_value()->type()->receiver();
      if (rcvr != NULL)
	{
	  Named_type* rcvr_type = rcvr->type()->deref()->named_type();
	  ret->append(Gogo::unpack_hidden_name(rcvr_type->name()));
	  ret->push_back('.');
	}
      ret->append(Gogo::unpack_hidden_name(this->in_function_->name()));
      ret->push_back('$');
      if (this->in_function_index_ > 0)
	{
	  char buf[30];
	  snprintf(buf, sizeof buf, "%u", this->in_function_index_);
	  ret->append(buf);
	  ret->push_back('$');
	}
      ret->push_back('\t');
    }
  ret->append(Gogo::unpack_hidden_name(this->named_object_->name()));
}

// Export the type.  This is called to export a global type.

void
Named_type::export_named_type(Export* exp, const std::string&) const
{
  // We don't need to write the name of the type here, because it will
  // be written by Export::write_type anyhow.
  exp->write_c_string("type ");
  exp->write_type(this);
  exp->write_c_string("\n");
}

// Import a named type.

void
Named_type::import_named_type(Import* imp, Named_type** ptype)
{
  imp->require_c_string("type ");
  Type *type = imp->read_type();
  *ptype = type->named_type();
  go_assert(*ptype != NULL);
  imp->require_semicolon_if_old_version();
  imp->require_c_string("\n");
}

// Export the type when it is referenced by another type.  In this
// case Export::export_type will already have issued the name.

void
Named_type::do_export(Export* exp) const
{
  exp->write_type(this->type_);

  // To save space, we only export the methods directly attached to
  // this type.
  Bindings* methods = this->local_methods_;
  if (methods == NULL)
    return;

  exp->write_c_string("\n");
  for (Bindings::const_definitions_iterator p = methods->begin_definitions();
       p != methods->end_definitions();
       ++p)
    {
      exp->write_c_string(" ");
      (*p)->export_named_object(exp);
    }

  for (Bindings::const_declarations_iterator p = methods->begin_declarations();
       p != methods->end_declarations();
       ++p)
    {
      if (p->second->is_function_declaration())
	{
	  exp->write_c_string(" ");
	  p->second->export_named_object(exp);
	}
    }
}

// Make a named type.

Named_type*
Type::make_named_type(Named_object* named_object, Type* type,
		      Location location)
{
  return new Named_type(named_object, type, location);
}

// Finalize the methods for TYPE.  It will be a named type or a struct
// type.  This sets *ALL_METHODS to the list of methods, and builds
// all required stubs.

void
Type::finalize_methods(Gogo* gogo, const Type* type, Location location,
		       Methods** all_methods)
{
  *all_methods = new Methods();
  std::vector<const Named_type*> seen;
  Type::add_methods_for_type(type, NULL, 0, false, false, &seen, *all_methods);
  if ((*all_methods)->empty())
    {
      delete *all_methods;
      *all_methods = NULL;
    }
  Type::build_stub_methods(gogo, type, *all_methods, location);
}

// Add the methods for TYPE to *METHODS.  FIELD_INDEXES is used to
// build up the struct field indexes as we go.  DEPTH is the depth of
// the field within TYPE.  IS_EMBEDDED_POINTER is true if we are
// adding these methods for an anonymous field with pointer type.
// NEEDS_STUB_METHOD is true if we need to use a stub method which
// calls the real method.  TYPES_SEEN is used to avoid infinite
// recursion.

void
Type::add_methods_for_type(const Type* type,
			   const Method::Field_indexes* field_indexes,
			   unsigned int depth,
			   bool is_embedded_pointer,
			   bool needs_stub_method,
			   std::vector<const Named_type*>* seen,
			   Methods* methods)
{
  // Pointer types may not have methods.
  if (type->points_to() != NULL)
    return;

  const Named_type* nt = type->named_type();
  if (nt != NULL)
    {
      for (std::vector<const Named_type*>::const_iterator p = seen->begin();
	   p != seen->end();
	   ++p)
	{
	  if (*p == nt)
	    return;
	}

      seen->push_back(nt);

      Type::add_local_methods_for_type(nt, field_indexes, depth,
				       is_embedded_pointer, needs_stub_method,
				       methods);
    }

  Type::add_embedded_methods_for_type(type, field_indexes, depth,
				      is_embedded_pointer, needs_stub_method,
				      seen, methods);

  // If we are called with depth > 0, then we are looking at an
  // anonymous field of a struct.  If such a field has interface type,
  // then we need to add the interface methods.  We don't want to add
  // them when depth == 0, because we will already handle them
  // following the usual rules for an interface type.
  if (depth > 0)
    Type::add_interface_methods_for_type(type, field_indexes, depth, methods);

  if (nt != NULL)
      seen->pop_back();
}

// Add the local methods for the named type NT to *METHODS.  The
// parameters are as for add_methods_to_type.

void
Type::add_local_methods_for_type(const Named_type* nt,
				 const Method::Field_indexes* field_indexes,
				 unsigned int depth,
				 bool is_embedded_pointer,
				 bool needs_stub_method,
				 Methods* methods)
{
  const Bindings* local_methods = nt->local_methods();
  if (local_methods == NULL)
    return;

  for (Bindings::const_declarations_iterator p =
	 local_methods->begin_declarations();
       p != local_methods->end_declarations();
       ++p)
    {
      Named_object* no = p->second;
      bool is_value_method = (is_embedded_pointer
			      || !Type::method_expects_pointer(no));
      Method* m = new Named_method(no, field_indexes, depth, is_value_method,
				   (needs_stub_method || depth > 0));
      if (!methods->insert(no->name(), m))
	delete m;
    }
}

// Add the embedded methods for TYPE to *METHODS.  These are the
// methods attached to anonymous fields.  The parameters are as for
// add_methods_to_type.

void
Type::add_embedded_methods_for_type(const Type* type,
				    const Method::Field_indexes* field_indexes,
				    unsigned int depth,
				    bool is_embedded_pointer,
				    bool needs_stub_method,
				    std::vector<const Named_type*>* seen,
				    Methods* methods)
{
  // Look for anonymous fields in TYPE.  TYPE has fields if it is a
  // struct.
  const Struct_type* st = type->struct_type();
  if (st == NULL)
    return;

  const Struct_field_list* fields = st->fields();
  if (fields == NULL)
    return;

  unsigned int i = 0;
  for (Struct_field_list::const_iterator pf = fields->begin();
       pf != fields->end();
       ++pf, ++i)
    {
      if (!pf->is_anonymous())
	continue;

      Type* ftype = pf->type();
      bool is_pointer = false;
      if (ftype->points_to() != NULL)
	{
	  ftype = ftype->points_to();
	  is_pointer = true;
	}
      Named_type* fnt = ftype->named_type();
      if (fnt == NULL)
	{
	  // This is an error, but it will be diagnosed elsewhere.
	  continue;
	}

      Method::Field_indexes* sub_field_indexes = new Method::Field_indexes();
      sub_field_indexes->next = field_indexes;
      sub_field_indexes->field_index = i;

      Methods tmp_methods;
      Type::add_methods_for_type(fnt, sub_field_indexes, depth + 1,
				 (is_embedded_pointer || is_pointer),
				 (needs_stub_method
				  || is_pointer
				  || i > 0),
				 seen,
				 &tmp_methods);
      // Check if there are promoted methods that conflict with field names and
      // don't add them to the method map.
      for (Methods::const_iterator p = tmp_methods.begin();
	   p != tmp_methods.end();
	   ++p)
	{
	  bool found = false;
	  for (Struct_field_list::const_iterator fp = fields->begin();
	       fp != fields->end();
	       ++fp)
	    {
	      if (fp->field_name() == p->first)
		{
		  found = true;
		  break;
		}
	    }
	  if (!found &&
	      !methods->insert(p->first, p->second))
	    delete p->second;
	}
    }
}

// If TYPE is an interface type, then add its method to *METHODS.
// This is for interface methods attached to an anonymous field.  The
// parameters are as for add_methods_for_type.

void
Type::add_interface_methods_for_type(const Type* type,
				     const Method::Field_indexes* field_indexes,
				     unsigned int depth,
				     Methods* methods)
{
  const Interface_type* it = type->interface_type();
  if (it == NULL)
    return;

  const Typed_identifier_list* imethods = it->methods();
  if (imethods == NULL)
    return;

  for (Typed_identifier_list::const_iterator pm = imethods->begin();
       pm != imethods->end();
       ++pm)
    {
      Function_type* fntype = pm->type()->function_type();
      if (fntype == NULL)
	{
	  // This is an error, but it should be reported elsewhere
	  // when we look at the methods for IT.
	  continue;
	}
      go_assert(!fntype->is_method());
      fntype = fntype->copy_with_receiver(const_cast<Type*>(type));
      Method* m = new Interface_method(pm->name(), pm->location(), fntype,
				       field_indexes, depth);
      if (!methods->insert(pm->name(), m))
	delete m;
    }
}

// Build stub methods for TYPE as needed.  METHODS is the set of
// methods for the type.  A stub method may be needed when a type
// inherits a method from an anonymous field.  When we need the
// address of the method, as in a type descriptor, we need to build a
// little stub which does the required field dereferences and jumps to
// the real method.  LOCATION is the location of the type definition.

void
Type::build_stub_methods(Gogo* gogo, const Type* type, const Methods* methods,
			 Location location)
{
  if (methods == NULL)
    return;
  for (Methods::const_iterator p = methods->begin();
       p != methods->end();
       ++p)
    {
      Method* m = p->second;
      if (m->is_ambiguous() || !m->needs_stub_method())
	continue;

      const std::string& name(p->first);

      // Build a stub method.

      const Function_type* fntype = m->type();

      static unsigned int counter;
      char buf[100];
      snprintf(buf, sizeof buf, "$this%u", counter);
      ++counter;

      Type* receiver_type = const_cast<Type*>(type);
      if (!m->is_value_method())
	receiver_type = Type::make_pointer_type(receiver_type);
      Location receiver_location = m->receiver_location();
      Typed_identifier* receiver = new Typed_identifier(buf, receiver_type,
							receiver_location);

      const Typed_identifier_list* fnparams = fntype->parameters();
      Typed_identifier_list* stub_params;
      if (fnparams == NULL || fnparams->empty())
	stub_params = NULL;
      else
	{
	  // We give each stub parameter a unique name.
	  stub_params = new Typed_identifier_list();
	  for (Typed_identifier_list::const_iterator pp = fnparams->begin();
	       pp != fnparams->end();
	       ++pp)
	    {
	      char pbuf[100];
	      snprintf(pbuf, sizeof pbuf, "$p%u", counter);
	      stub_params->push_back(Typed_identifier(pbuf, pp->type(),
						      pp->location()));
	      ++counter;
	    }
	}

      const Typed_identifier_list* fnresults = fntype->results();
      Typed_identifier_list* stub_results;
      if (fnresults == NULL || fnresults->empty())
	stub_results = NULL;
      else
	{
	  // We create the result parameters without any names, since
	  // we won't refer to them.
	  stub_results = new Typed_identifier_list();
	  for (Typed_identifier_list::const_iterator pr = fnresults->begin();
	       pr != fnresults->end();
	       ++pr)
	    stub_results->push_back(Typed_identifier("", pr->type(),
						     pr->location()));
	}

      Function_type* stub_type = Type::make_function_type(receiver,
							  stub_params,
							  stub_results,
							  fntype->location());
      if (fntype->is_varargs())
	stub_type->set_is_varargs();

      // We only create the function in the package which creates the
      // type.
      const Package* package;
      if (type->named_type() == NULL)
	package = NULL;
      else
	package = type->named_type()->named_object()->package();
      std::string stub_name = gogo->stub_method_name(package, name);
      Named_object* stub;
      if (package != NULL)
	stub = Named_object::make_function_declaration(stub_name, package,
						       stub_type, location);
      else
	{
	  stub = gogo->start_function(stub_name, stub_type, false,
				      fntype->location());
	  Type::build_one_stub_method(gogo, m, buf, stub_params,
				      fntype->is_varargs(), location);
	  gogo->finish_function(fntype->location());

	  if (type->named_type() == NULL && stub->is_function())
	    stub->func_value()->set_is_unnamed_type_stub_method();
	  if (m->nointerface() && stub->is_function())
	    stub->func_value()->set_nointerface();
	}

      m->set_stub_object(stub);
    }
}

// Build a stub method which adjusts the receiver as required to call
// METHOD.  RECEIVER_NAME is the name we used for the receiver.
// PARAMS is the list of function parameters.

void
Type::build_one_stub_method(Gogo* gogo, Method* method,
			    const char* receiver_name,
			    const Typed_identifier_list* params,
			    bool is_varargs,
			    Location location)
{
  Named_object* receiver_object = gogo->lookup(receiver_name, NULL);
  go_assert(receiver_object != NULL);

  Expression* expr = Expression::make_var_reference(receiver_object, location);
  expr = Type::apply_field_indexes(expr, method->field_indexes(), location);
  if (expr->type()->points_to() == NULL)
    expr = Expression::make_unary(OPERATOR_AND, expr, location);

  Expression_list* arguments;
  if (params == NULL || params->empty())
    arguments = NULL;
  else
    {
      arguments = new Expression_list();
      for (Typed_identifier_list::const_iterator p = params->begin();
	   p != params->end();
	   ++p)
	{
	  Named_object* param = gogo->lookup(p->name(), NULL);
	  go_assert(param != NULL);
	  Expression* param_ref = Expression::make_var_reference(param,
								 location);
	  arguments->push_back(param_ref);
	}
    }

  Expression* func = method->bind_method(expr, location);
  go_assert(func != NULL);
  Call_expression* call = Expression::make_call(func, arguments, is_varargs,
						location);

  gogo->add_statement(Statement::make_return_from_call(call, location));
}

// Apply FIELD_INDEXES to EXPR.  The field indexes have to be applied
// in reverse order.

Expression*
Type::apply_field_indexes(Expression* expr,
			  const Method::Field_indexes* field_indexes,
			  Location location)
{
  if (field_indexes == NULL)
    return expr;
  expr = Type::apply_field_indexes(expr, field_indexes->next, location);
  Struct_type* stype = expr->type()->deref()->struct_type();
  go_assert(stype != NULL
	     && field_indexes->field_index < stype->field_count());
  if (expr->type()->struct_type() == NULL)
    {
      go_assert(expr->type()->points_to() != NULL);
      expr = Expression::make_dereference(expr, Expression::NIL_CHECK_DEFAULT,
                                          location);
      go_assert(expr->type()->struct_type() == stype);
    }
  return Expression::make_field_reference(expr, field_indexes->field_index,
					  location);
}

// Return whether NO is a method for which the receiver is a pointer.

bool
Type::method_expects_pointer(const Named_object* no)
{
  const Function_type *fntype;
  if (no->is_function())
    fntype = no->func_value()->type();
  else if (no->is_function_declaration())
    fntype = no->func_declaration_value()->type();
  else
    go_unreachable();
  return fntype->receiver()->type()->points_to() != NULL;
}

// Given a set of methods for a type, METHODS, return the method NAME,
// or NULL if there isn't one or if it is ambiguous.  If IS_AMBIGUOUS
// is not NULL, then set *IS_AMBIGUOUS to true if the method exists
// but is ambiguous (and return NULL).

Method*
Type::method_function(const Methods* methods, const std::string& name,
		      bool* is_ambiguous)
{
  if (is_ambiguous != NULL)
    *is_ambiguous = false;
  if (methods == NULL)
    return NULL;
  Methods::const_iterator p = methods->find(name);
  if (p == methods->end())
    return NULL;
  Method* m = p->second;
  if (m->is_ambiguous())
    {
      if (is_ambiguous != NULL)
	*is_ambiguous = true;
      return NULL;
    }
  return m;
}

// Return a pointer to the interface method table for TYPE for the
// interface INTERFACE.

Expression*
Type::interface_method_table(Type* type,
			     Interface_type *interface,
			     bool is_pointer,
			     Interface_method_tables** method_tables,
			     Interface_method_tables** pointer_tables)
{
  go_assert(!interface->is_empty());

  Interface_method_tables** pimt = is_pointer ? method_tables : pointer_tables;

  if (*pimt == NULL)
    *pimt = new Interface_method_tables(5);

  std::pair<Interface_type*, Expression*> val(interface, NULL);
  std::pair<Interface_method_tables::iterator, bool> ins = (*pimt)->insert(val);

  Location loc = Linemap::predeclared_location();
  if (ins.second)
    {
      // This is a new entry in the hash table.
      go_assert(ins.first->second == NULL);
      ins.first->second =
	Expression::make_interface_mtable_ref(interface, type, is_pointer, loc);
    }
  return Expression::make_unary(OPERATOR_AND, ins.first->second, loc);
}

// Look for field or method NAME for TYPE.  Return an Expression for
// the field or method bound to EXPR.  If there is no such field or
// method, give an appropriate error and return an error expression.

Expression*
Type::bind_field_or_method(Gogo* gogo, const Type* type, Expression* expr,
			   const std::string& name,
			   Location location)
{
  if (type->deref()->is_error_type())
    return Expression::make_error(location);

  const Named_type* nt = type->deref()->named_type();
  const Struct_type* st = type->deref()->struct_type();
  const Interface_type* it = type->interface_type();

  // If this is a pointer to a pointer, then it is possible that the
  // pointed-to type has methods.
  bool dereferenced = false;
  if (nt == NULL
      && st == NULL
      && it == NULL
      && type->points_to() != NULL
      && type->points_to()->points_to() != NULL)
    {
      expr = Expression::make_dereference(expr, Expression::NIL_CHECK_DEFAULT,
                                          location);
      type = type->points_to();
      if (type->deref()->is_error_type())
	return Expression::make_error(location);
      nt = type->points_to()->named_type();
      st = type->points_to()->struct_type();
      dereferenced = true;
    }

  bool receiver_can_be_pointer = (expr->type()->points_to() != NULL
				  || expr->is_addressable());
  std::vector<const Named_type*> seen;
  bool is_method = false;
  bool found_pointer_method = false;
  std::string ambig1;
  std::string ambig2;
  if (Type::find_field_or_method(type, name, receiver_can_be_pointer,
				 &seen, NULL, &is_method,
				 &found_pointer_method, &ambig1, &ambig2))
    {
      Expression* ret;
      if (!is_method)
	{
	  go_assert(st != NULL);
	  if (type->struct_type() == NULL)
	    {
              if (dereferenced)
                {
                  go_error_at(location, "pointer type has no field %qs",
                              Gogo::message_name(name).c_str());
                  return Expression::make_error(location);
                }
	      go_assert(type->points_to() != NULL);
              expr = Expression::make_dereference(expr,
                                                  Expression::NIL_CHECK_DEFAULT,
                                                  location);
	      go_assert(expr->type()->struct_type() == st);
	    }
	  ret = st->field_reference(expr, name, location);
          if (ret == NULL)
            {
              go_error_at(location, "type has no field %qs",
                          Gogo::message_name(name).c_str());
              return Expression::make_error(location);
            }
	}
      else if (it != NULL && it->find_method(name) != NULL)
	ret = Expression::make_interface_field_reference(expr, name,
							 location);
      else
	{
	  Method* m;
	  if (nt != NULL)
	    m = nt->method_function(name, NULL);
	  else if (st != NULL)
	    m = st->method_function(name, NULL);
	  else
	    go_unreachable();
	  go_assert(m != NULL);
	  if (dereferenced)
	    {
	      go_error_at(location,
			  "calling method %qs requires explicit dereference",
			  Gogo::message_name(name).c_str());
	      return Expression::make_error(location);
	    }
	  if (!m->is_value_method() && expr->type()->points_to() == NULL)
	    expr = Expression::make_unary(OPERATOR_AND, expr, location);
	  ret = m->bind_method(expr, location);
	}
      go_assert(ret != NULL);
      return ret;
    }
  else
    {
      if (Gogo::is_erroneous_name(name))
	{
	  // An error was already reported.
	}
      else if (!ambig1.empty())
	go_error_at(location, "%qs is ambiguous via %qs and %qs",
		    Gogo::message_name(name).c_str(), ambig1.c_str(),
		    ambig2.c_str());
      else if (found_pointer_method)
	go_error_at(location, "method requires a pointer receiver");
      else if (nt == NULL && st == NULL && it == NULL)
	go_error_at(location,
		    ("reference to field %qs in object which "
		     "has no fields or methods"),
		    Gogo::message_name(name).c_str());
      else
	{
	  bool is_unexported;
	  // The test for 'a' and 'z' is to handle builtin names,
	  // which are not hidden.
	  if (!Gogo::is_hidden_name(name) && (name[0] < 'a' || name[0] > 'z'))
	    is_unexported = false;
	  else
	    {
	      std::string unpacked = Gogo::unpack_hidden_name(name);
	      seen.clear();
	      is_unexported = Type::is_unexported_field_or_method(gogo, type,
								  unpacked,
								  &seen);
	    }
	  if (is_unexported)
	    go_error_at(location, "reference to unexported field or method %qs",
			Gogo::message_name(name).c_str());
	  else
	    go_error_at(location, "reference to undefined field or method %qs",
			Gogo::message_name(name).c_str());
	}
      return Expression::make_error(location);
    }
}

// Look in TYPE for a field or method named NAME, return true if one
// is found.  This looks through embedded anonymous fields and handles
// ambiguity.  If a method is found, sets *IS_METHOD to true;
// otherwise, if a field is found, set it to false.  If
// RECEIVER_CAN_BE_POINTER is false, then the receiver is a value
// whose address can not be taken.  SEEN is used to avoid infinite
// recursion on invalid types.

// When returning false, this sets *FOUND_POINTER_METHOD if we found a
// method we couldn't use because it requires a pointer.  LEVEL is
// used for recursive calls, and can be NULL for a non-recursive call.
// When this function returns false because it finds that the name is
// ambiguous, it will store a path to the ambiguous names in *AMBIG1
// and *AMBIG2.  If the name is not found at all, *AMBIG1 and *AMBIG2
// will be unchanged.

// This function just returns whether or not there is a field or
// method, and whether it is a field or method.  It doesn't build an
// expression to refer to it.  If it is a method, we then look in the
// list of all methods for the type.  If it is a field, the search has
// to be done again, looking only for fields, and building up the
// expression as we go.

bool
Type::find_field_or_method(const Type* type,
			   const std::string& name,
			   bool receiver_can_be_pointer,
			   std::vector<const Named_type*>* seen,
			   int* level,
			   bool* is_method,
			   bool* found_pointer_method,
			   std::string* ambig1,
			   std::string* ambig2)
{
  // Named types can have locally defined methods.
  const Named_type* nt = type->unalias()->named_type();
  if (nt == NULL && type->points_to() != NULL)
    nt = type->points_to()->unalias()->named_type();
  if (nt != NULL)
    {
      Named_object* no = nt->find_local_method(name);
      if (no != NULL)
	{
	  if (receiver_can_be_pointer || !Type::method_expects_pointer(no))
	    {
	      *is_method = true;
	      return true;
	    }

	  // Record that we have found a pointer method in order to
	  // give a better error message if we don't find anything
	  // else.
	  *found_pointer_method = true;
	}

      for (std::vector<const Named_type*>::const_iterator p = seen->begin();
	   p != seen->end();
	   ++p)
	{
	  if (*p == nt)
	    {
	      // We've already seen this type when searching for methods.
	      return false;
	    }
	}
    }

  // Interface types can have methods.
  const Interface_type* it = type->interface_type();
  if (it != NULL && it->find_method(name) != NULL)
    {
      *is_method = true;
      return true;
    }

  // Struct types can have fields.  They can also inherit fields and
  // methods from anonymous fields.
  const Struct_type* st = type->deref()->struct_type();
  if (st == NULL)
    return false;
  const Struct_field_list* fields = st->fields();
  if (fields == NULL)
    return false;

  if (nt != NULL)
    seen->push_back(nt);

  int found_level = 0;
  bool found_is_method = false;
  std::string found_ambig1;
  std::string found_ambig2;
  const Struct_field* found_parent = NULL;
  for (Struct_field_list::const_iterator pf = fields->begin();
       pf != fields->end();
       ++pf)
    {
      if (pf->is_field_name(name))
	{
	  *is_method = false;
	  if (nt != NULL)
	    seen->pop_back();
	  return true;
	}

      if (!pf->is_anonymous())
	continue;

      if (pf->type()->deref()->is_error_type()
	  || pf->type()->deref()->is_undefined())
	continue;

      Named_type* fnt = pf->type()->named_type();
      if (fnt == NULL)
	fnt = pf->type()->deref()->named_type();
      go_assert(fnt != NULL);

      // Methods with pointer receivers on embedded field are
      // inherited by the pointer to struct, and also by the struct
      // type if the field itself is a pointer.
      bool can_be_pointer = (receiver_can_be_pointer
			     || pf->type()->points_to() != NULL);
      int sublevel = level == NULL ? 1 : *level + 1;
      bool sub_is_method;
      std::string subambig1;
      std::string subambig2;
      bool subfound = Type::find_field_or_method(fnt,
						 name,
						 can_be_pointer,
						 seen,
						 &sublevel,
						 &sub_is_method,
						 found_pointer_method,
						 &subambig1,
						 &subambig2);
      if (!subfound)
	{
	  if (!subambig1.empty())
	    {
	      // The name was found via this field, but is ambiguous.
	      // if the ambiguity is lower or at the same level as
	      // anything else we have already found, then we want to
	      // pass the ambiguity back to the caller.
	      if (found_level == 0 || sublevel <= found_level)
		{
		  found_ambig1 = (Gogo::message_name(pf->field_name())
				  + '.' + subambig1);
		  found_ambig2 = (Gogo::message_name(pf->field_name())
				  + '.' + subambig2);
		  found_level = sublevel;
		}
	    }
	}
      else
	{
	  // The name was found via this field.  Use the level to see
	  // if we want to use this one, or whether it introduces an
	  // ambiguity.
	  if (found_level == 0 || sublevel < found_level)
	    {
	      found_level = sublevel;
	      found_is_method = sub_is_method;
	      found_ambig1.clear();
	      found_ambig2.clear();
	      found_parent = &*pf;
	    }
	  else if (sublevel > found_level)
	    ;
	  else if (found_ambig1.empty())
	    {
	      // We found an ambiguity.
	      go_assert(found_parent != NULL);
	      found_ambig1 = Gogo::message_name(found_parent->field_name());
	      found_ambig2 = Gogo::message_name(pf->field_name());
	    }
	  else
	    {
	      // We found an ambiguity, but we already know of one.
	      // Just report the earlier one.
	    }
	}
    }

  // Here if we didn't find anything FOUND_LEVEL is 0.  If we found
  // something ambiguous, FOUND_LEVEL is not 0 and FOUND_AMBIG1 and
  // FOUND_AMBIG2 are not empty.  If we found the field, FOUND_LEVEL
  // is not 0 and FOUND_AMBIG1 and FOUND_AMBIG2 are empty.

  if (nt != NULL)
    seen->pop_back();

  if (found_level == 0)
    return false;
  else if (found_is_method
	   && type->named_type() != NULL
	   && type->points_to() != NULL)
    {
      // If this is a method inherited from a struct field in a named pointer
      // type, it is invalid to automatically dereference the pointer to the
      // struct to find this method.
      if (level != NULL)
	*level = found_level;
      *is_method = true;
      return false;
    }
  else if (!found_ambig1.empty())
    {
      go_assert(!found_ambig1.empty());
      ambig1->assign(found_ambig1);
      ambig2->assign(found_ambig2);
      if (level != NULL)
	*level = found_level;
      return false;
    }
  else
    {
      if (level != NULL)
	*level = found_level;
      *is_method = found_is_method;
      return true;
    }
}

// Return whether NAME is an unexported field or method for TYPE.

bool
Type::is_unexported_field_or_method(Gogo* gogo, const Type* type,
				    const std::string& name,
				    std::vector<const Named_type*>* seen)
{
  const Named_type* nt = type->named_type();
  if (nt == NULL)
    nt = type->deref()->named_type();
  if (nt != NULL)
    {
      if (nt->is_unexported_local_method(gogo, name))
	return true;

      for (std::vector<const Named_type*>::const_iterator p = seen->begin();
	   p != seen->end();
	   ++p)
	{
	  if (*p == nt)
	    {
	      // We've already seen this type.
	      return false;
	    }
	}
    }

  const Interface_type* it = type->interface_type();
  if (it != NULL && it->is_unexported_method(gogo, name))
    return true;

  type = type->deref();

  const Struct_type* st = type->struct_type();
  if (st != NULL && st->is_unexported_local_field(gogo, name))
    return true;

  if (st == NULL)
    return false;

  const Struct_field_list* fields = st->fields();
  if (fields == NULL)
    return false;

  if (nt != NULL)
    seen->push_back(nt);

  for (Struct_field_list::const_iterator pf = fields->begin();
       pf != fields->end();
       ++pf)
    {
      if (pf->is_anonymous()
	  && !pf->type()->deref()->is_error_type()
	  && !pf->type()->deref()->is_undefined())
	{
	  Named_type* subtype = pf->type()->named_type();
	  if (subtype == NULL)
	    subtype = pf->type()->deref()->named_type();
	  if (subtype == NULL)
	    {
	      // This is an error, but it will be diagnosed elsewhere.
	      continue;
	    }
	  if (Type::is_unexported_field_or_method(gogo, subtype, name, seen))
	    {
	      if (nt != NULL)
		seen->pop_back();
	      return true;
	    }
	}
    }

  if (nt != NULL)
    seen->pop_back();

  return false;
}

// Class Forward_declaration.

Forward_declaration_type::Forward_declaration_type(Named_object* named_object)
  : Type(TYPE_FORWARD),
    named_object_(named_object->resolve()), warned_(false)
{
  go_assert(this->named_object_->is_unknown()
	     || this->named_object_->is_type_declaration());
}

// Return the named object.

Named_object*
Forward_declaration_type::named_object()
{
  return this->named_object_->resolve();
}

const Named_object*
Forward_declaration_type::named_object() const
{
  return this->named_object_->resolve();
}

// Return the name of the forward declared type.

const std::string&
Forward_declaration_type::name() const
{
  return this->named_object()->name();
}

// Warn about a use of a type which has been declared but not defined.

void
Forward_declaration_type::warn() const
{
  Named_object* no = this->named_object_->resolve();
  if (no->is_unknown())
    {
      // The name was not defined anywhere.
      if (!this->warned_)
	{
	  go_error_at(this->named_object_->location(),
		      "use of undefined type %qs",
		      no->message_name().c_str());
	  this->warned_ = true;
	}
    }
  else if (no->is_type_declaration())
    {
      // The name was seen as a type, but the type was never defined.
      if (no->type_declaration_value()->using_type())
	{
	  go_error_at(this->named_object_->location(),
		      "use of undefined type %qs",
		      no->message_name().c_str());
	  this->warned_ = true;
	}
    }
  else
    {
      // The name was defined, but not as a type.
      if (!this->warned_)
	{
	  go_error_at(this->named_object_->location(), "expected type");
	  this->warned_ = true;
	}
    }
}

// Get the base type of a declaration.  This gives an error if the
// type has not yet been defined.

Type*
Forward_declaration_type::real_type()
{
  if (this->is_defined())
    {
      Named_type* nt = this->named_object()->type_value();
      if (!nt->is_valid())
	return Type::make_error_type();
      return this->named_object()->type_value();
    }
  else
    {
      this->warn();
      return Type::make_error_type();
    }
}

const Type*
Forward_declaration_type::real_type() const
{
  if (this->is_defined())
    {
      const Named_type* nt = this->named_object()->type_value();
      if (!nt->is_valid())
	return Type::make_error_type();
      return this->named_object()->type_value();
    }
  else
    {
      this->warn();
      return Type::make_error_type();
    }
}

// Return whether the base type is defined.

bool
Forward_declaration_type::is_defined() const
{
  return this->named_object()->is_type();
}

// Add a method.  This is used when methods are defined before the
// type.

Named_object*
Forward_declaration_type::add_method(const std::string& name,
				     Function* function)
{
  Named_object* no = this->named_object();
  if (no->is_unknown())
    no->declare_as_type();
  return no->type_declaration_value()->add_method(name, function);
}

// Add a method declaration.  This is used when methods are declared
// before the type.

Named_object*
Forward_declaration_type::add_method_declaration(const std::string& name,
						 Package* package,
						 Function_type* type,
						 Location location)
{
  Named_object* no = this->named_object();
  if (no->is_unknown())
    no->declare_as_type();
  Type_declaration* td = no->type_declaration_value();
  return td->add_method_declaration(name, package, type, location);
}

// Add an already created object as a method.

void
Forward_declaration_type::add_existing_method(Named_object* nom)
{
  Named_object* no = this->named_object();
  if (no->is_unknown())
    no->declare_as_type();
  no->type_declaration_value()->add_existing_method(nom);
}

// Traversal.

int
Forward_declaration_type::do_traverse(Traverse* traverse)
{
  if (this->is_defined()
      && Type::traverse(this->real_type(), traverse) == TRAVERSE_EXIT)
    return TRAVERSE_EXIT;
  return TRAVERSE_CONTINUE;
}

// Verify the type.

bool
Forward_declaration_type::do_verify()
{
  if (!this->is_defined() && !this->is_nil_constant_as_type())
    {
      this->warn();
      return false;
    }
  return true;
}

// Get the backend representation for the type.

Btype*
Forward_declaration_type::do_get_backend(Gogo* gogo)
{
  if (this->is_defined())
    return Type::get_named_base_btype(gogo, this->real_type());

  if (this->warned_)
    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);
  return gogo->backend()->named_type(this->name(), bt,
				     this->named_object()->location());
}

// Build a type descriptor for a forwarded type.

Expression*
Forward_declaration_type::do_type_descriptor(Gogo* gogo, Named_type* name)
{
  Location ploc = Linemap::predeclared_location();
  if (!this->is_defined())
    return Expression::make_error(ploc);
  else
    {
      Type* t = this->real_type();
      if (name != NULL)
	return this->named_type_descriptor(gogo, t, name);
      else
	return Expression::make_error(this->named_object_->location());
    }
}

// The reflection string.

void
Forward_declaration_type::do_reflection(Gogo* gogo, std::string* ret) const
{
  this->append_reflection(this->real_type(), gogo, ret);
}

// Export a forward declaration.  This can happen when a defined type
// refers to a type which is only declared (and is presumably defined
// in some other file in the same package).

void
Forward_declaration_type::do_export(Export*) const
{
  // If there is a base type, that should be exported instead of this.
  go_assert(!this->is_defined());

  // We don't output anything.
}

// Make a forward declaration.

Type*
Type::make_forward_declaration(Named_object* named_object)
{
  return new Forward_declaration_type(named_object);
}

// Class Typed_identifier_list.

// Sort the entries by name.

struct Typed_identifier_list_sort
{
 public:
  bool
  operator()(const Typed_identifier& t1, const Typed_identifier& t2) const
  {
    return (Gogo::unpack_hidden_name(t1.name())
	    < Gogo::unpack_hidden_name(t2.name()));
  }
};

void
Typed_identifier_list::sort_by_name()
{
  std::sort(this->entries_.begin(), this->entries_.end(),
	    Typed_identifier_list_sort());
}

// Traverse types.

int
Typed_identifier_list::traverse(Traverse* traverse) const
{
  for (Typed_identifier_list::const_iterator p = this->begin();
       p != this->end();
       ++p)
    {
      if (Type::traverse(p->type(), traverse) == TRAVERSE_EXIT)
	return TRAVERSE_EXIT;
    }
  return TRAVERSE_CONTINUE;
}

// Copy the list.

Typed_identifier_list*
Typed_identifier_list::copy() const
{
  Typed_identifier_list* ret = new Typed_identifier_list();
  for (Typed_identifier_list::const_iterator p = this->begin();
       p != this->end();
       ++p)
    ret->push_back(Typed_identifier(p->name(), p->type(), p->location()));
  return ret;
}
