// 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, Struct_type* type, 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.
  t1 = t1->forwarded();
  t2 = t2->forwarded();

  if ((flags & COMPARE_ALIASES) == 0)
    {
      // 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
{
  const Type* t = this->forwarded();
  if (t->named_type() != NULL && t->named_type()->is_alias())
    {
      unsigned int r =
	t->named_type()->real_type()->hash_for_method(gogo, flags);
      if ((flags & Type::COMPARE_ALIASES) != 0)
	r += TYPE_FORWARD;
      return r;
    }
  unsigned int ret = t->classification_;
  return ret + t->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;
}

// 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;
	}

      // We set the has_padding field of a Struct_type when we convert
      // to the backend type, so if we have multiple Struct_type's
      // mapping to the same backend type we need to copy the
      // has_padding field.  FIXME: This is awkward.  We shouldn't
      // really change the type when setting the backend type, but
      // there isn't any other good time to add the padding field.
      if (ins.first->first->struct_type() != NULL
	  && ins.first->first->struct_type()->has_padding())
	this->struct_type()->set_has_padding();

      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(), 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 whether this type is stored directly in an interface's
// data word.
//
// Since finalize_methods runs before type checking, we may see a
// malformed type like 'type T struct { x T }'. Use a visited map
// to avoid infinite recursion.

bool
Type::is_direct_iface_type() const
{
  Unordered_set(const Type*) visited;
  return this->is_direct_iface_type_helper(&visited);
}

bool
Type::is_direct_iface_type_helper(Unordered_set(const Type*)* visited) const
{
  if (this->points_to() != NULL
      || this->channel_type() != NULL
      || this->function_type() != NULL
      || this->map_type() != NULL)
    return true;

  std::pair<Unordered_set(const Type*)::iterator, bool> ins
    = visited->insert(this);
  if (!ins.second)
    // malformed circular type
    return false;

  const Struct_type* st = this->struct_type();
  if (st != NULL)
    return (st->field_count() == 1
            && st->field(0)->type()->is_direct_iface_type_helper(visited));
  const Array_type* at = this->array_type();
  if (at != NULL && !at->is_slice_type())
    {
      int64_t len;
      return (at->int_length(&len) && len == 1
              && at->element_type()->is_direct_iface_type_helper(visited));
    }
  return false;
}

// 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->is_direct_iface_type())
    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));
    }

  bool use_direct_iface_stub =
    this->points_to() != NULL
    && this->points_to()->is_direct_iface_type()
    && m->is_value_method();
  Named_object* no = (use_direct_iface_stub
                      ? m->iface_stub_object()
                      : (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()
                                && !use_direct_iface_stub);
  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 = Gogo::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,
          // except for direct interface types where the interface call
          // actually passes value.
          Type* rtype = this->receiver_->type();
          if (!rtype->is_direct_iface_type())
            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 computing the hash value of an instance of this
// struct type might panic.

bool
Struct_type::do_hash_might_panic()
{
  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()->hash_might_panic())
	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, Struct_type* type, bool use_placeholder,
			  std::vector<Backend::Btyped_identifier>* bfields)
{
  const Struct_field_list* fields = type->fields();
  bfields->resize(fields->size());
  size_t i = 0;
  int64_t lastsize = 0;
  bool saw_nonzero = false;
  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();
      lastsize = gogo->backend()->type_size((*bfields)[i].btype);
      if (lastsize != 0)
        saw_nonzero = true;
    }
  go_assert(i == fields->size());
  if (saw_nonzero && lastsize == 0)
    {
      // For nonzero-sized structs which end in a zero-sized thing, we add
      // an extra byte of padding to the type. This padding ensures that
      // taking the address of the zero-sized thing can't manufacture a
      // pointer to the next object in the heap. See issue 9401.
      size_t n = fields->size();
      bfields->resize(n + 1);
      (*bfields)[n].name = "_";
      (*bfields)[n].btype = Type::lookup_integer_type("uint8")->get_backend(gogo);
      (*bfields)[n].location = (*bfields)[n-1].location;
      type->set_has_padding();
    }
}

// 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, 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());

	  Export_function_body efb(exp, 0);
	  expr->export_expression(&efb);
	  exp->write_string(efb.body());

	  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,
							       imp->location());
	      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) const
{
  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)
    {
      Numeric_constant nc;
      mpz_t val;
      if (!this->length_->numeric_constant_value(&nc) || !nc.to_int(&val))
        {
	  go_assert(saw_errors());
          return;
        }
      char* s = mpz_get_str(NULL, 10, val);
      exp->write_string(s);
      exp->write_string(" ");
      mpz_clear(val);
    }
  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->location());
  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* uint32_type = Type::lookup_integer_type("uint32");

      Struct_type* sf =
	Type::make_builtin_struct_type(8,
				       "", tdt,
				       "key", ptdt,
				       "elem", ptdt,
				       "bucket", ptdt,
				       "keysize", uint8_type,
				       "valuesize", uint8_type,
				       "bucketsize", uint16_type,
				       "flags", uint32_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");
  Type* uint32_type = Type::lookup_integer_type("uint32");

  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("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("bucketsize"));
  vals->push_back(Expression::make_integer_int64(bucketsize, uint16_type,
						 bloc));

  ++p;
  go_assert(p->is_field_name("flags"));
  // As with the other fields, the flag bits must match the reflect
  // and runtime packages.
  unsigned long flags = 0;
  if (keysize > Map_type::max_key_size)
    flags |= 1;
  if (valsize > Map_type::max_val_size)
    flags |= 2;
  if (this->key_type_->is_reflexive())
    flags |= 4;
  if (this->key_type_->needs_key_update())
    flags |= 8;
  if (this->key_type_->hash_might_panic())
    flags |= 16;
  vals->push_back(Expression::make_integer_ul(flags, uint32_type, 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;

  // Consult a flag to see whether we need to compare based on
  // parse methods or all methods.
  Typed_identifier_list* methods = (((flags & COMPARE_EMBEDDED_INTERFACES) != 0)
				      ? this->parse_methods_
                                      : this->all_methods_);
  Typed_identifier_list* tmethods = (((flags & COMPARE_EMBEDDED_INTERFACES) != 0)
				       ? t->parse_methods_
				       : t->all_methods_);

  // We require the same methods with the same types.  The methods
  // have already been sorted.
  if (methods == NULL || tmethods == NULL)
    return methods == tmethods;

  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 = methods->begin();
  Typed_identifier_list::const_iterator p2;
  for (p2 = tmethods->begin(); p2 != tmethods->end(); ++p1, ++p2)
    {
      if (p1 == 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 == methods->end() && p2 == tmethods->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 = Gogo::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,
					    this->named_object_->package(),
					    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:
          if (type->named_type() == type->base()->named_type())
            {
              this->found_ = true;
              return TRAVERSE_EXIT;
            }
          else
	    go_assert(saw_errors());
	break;

	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;
    }

  // Check if there are recursive inherited interface aliases.
  Interface_type* ift = type->interface_type();
  if (ift != NULL)
    {
      const Typed_identifier_list* methods = ift->local_methods();
      if (methods == NULL)
	return TRAVERSE_CONTINUE;
      for (Typed_identifier_list::const_iterator p = methods->begin();
	   p != methods->end();
	   ++p)
	if (p->name().empty() && p->type()->named_type() == this->find_type_)
	  {
	    this->found_ = true;
	    return TRAVERSE_EXIT;
	  }
    }

  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 = Gogo::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 = Gogo::hash_string(gogo->pkgpath(), ret);
      else
	ret = Gogo::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(), 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()));
}

// Import a named type.  This is only used for export format versions
// before version 3.

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.  The
// output always ends with a newline, since that is convenient if
// there are methods.

void
Named_type::do_export(Export* exp) const
{
  exp->write_type(this->type_);
  exp->write_c_string("\n");

  // To save space, we only export the methods directly attached to
  // this type.
  Bindings* methods = this->local_methods_;
  if (methods == NULL)
    return;

  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);
  if (type->is_direct_iface_type())
    Type::build_direct_iface_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));
}

// Build direct interface stub methods for TYPE as needed.  METHODS
// is the set of methods for the type.  LOCATION is the location of
// the type definition.
//
// This is for an interface holding a pointer to the type and invoking
// a value method.  The interface data is the pointer, and is passed
// to the stub, which dereferences it and passes to the actual method.

void
Type::build_direct_iface_stub_methods(Gogo* gogo, const Type* type,
                                      Methods* methods, Location loc)
{
  if (methods == NULL)
    return;

  for (Methods::const_iterator p = methods->begin();
       p != methods->end();
       ++p)
    {
      Method* m = p->second;
      if (!m->is_value_method())
        continue;

      Type* receiver_type = const_cast<Type*>(type);
      receiver_type = Type::make_pointer_type(receiver_type);
      const std::string& name(p->first);
      Function_type* fntype = m->type();

      static unsigned int counter;
      char buf[100];
      snprintf(buf, sizeof buf, "$ptr%u", counter);
      ++counter;
      Typed_identifier* receiver =
        new Typed_identifier(buf, receiver_type, m->receiver_location());

      const Typed_identifier_list* params = fntype->parameters();
      Typed_identifier_list* stub_params;
      if (params == NULL || params->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 = params->begin();
               pp != params->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) + "2";
      Named_object* stub;
      if (package != NULL)
        stub = Named_object::make_function_declaration(stub_name, package,
                                                       stub_type, loc);
      else
        {
          stub = gogo->start_function(stub_name, stub_type, false,
                                      fntype->location());
          Type::build_one_iface_stub_method(gogo, m, buf, stub_params,
                                            fntype->is_varargs(), loc);
          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_iface_stub_object(stub);
    }
}

// Build a stub method for METHOD of direct interface type T.
// RECEIVER_NAME is the name we used for the receiver.
// PARAMS is the list of function parameters.
//
// The stub looks like
//
// func ($ptr *T, PARAMS) {
//   (*$ptr).METHOD(PARAMS)
// }

void
Type::build_one_iface_stub_method(Gogo* gogo, Method* method,
                                  const char* receiver_name,
                                  const Typed_identifier_list* params,
                                  bool is_varargs, Location loc)
{
  Named_object* receiver_object = gogo->lookup(receiver_name, NULL);
  go_assert(receiver_object != NULL);

  Expression* expr = Expression::make_var_reference(receiver_object, loc);
  expr = Expression::make_dereference(expr,
                                      Expression::NIL_CHECK_DEFAULT,
                                      loc);

  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,
                                                                 loc);
          arguments->push_back(param_ref);
        }
    }

  Expression* func = method->bind_method(expr, loc);
  go_assert(func != NULL);
  Call_expression* call = Expression::make_call(func, arguments, is_varargs,
                                                loc);

  gogo->add_statement(Statement::make_return_from_call(call, loc));
}

// 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;
}
