// import.cc -- Go frontend import declarations.

// 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 "filenames.h"

#include "go-c.h"
#include "go-diagnostics.h"
#include "gogo.h"
#include "lex.h"
#include "types.h"
#include "export.h"
#include "import.h"

#ifndef O_BINARY
#define O_BINARY 0
#endif

// The list of paths we search for import files.

static std::vector<std::string> search_path;

// Add a directory to the search path.  This is called from the option
// handling language hook.

GO_EXTERN_C
void
go_add_search_path(const char* path)
{
  search_path.push_back(std::string(path));
}

// Find import data.  This searches the file system for FILENAME and
// returns a pointer to a Stream object to read the data that it
// exports.  If the file is not found, it returns NULL.

// When FILENAME is not an absolute path and does not start with ./ or
// ../, we use the search path provided by -I and -L options.

// When FILENAME does start with ./ or ../, we use
// RELATIVE_IMPORT_PATH as a prefix.

// When FILENAME does not exist, we try modifying FILENAME to find the
// file.  We use the first of these which exists:
//   * We append ".gox".
//   * We turn the base of FILENAME into libFILENAME.so.
//   * We turn the base of FILENAME into libFILENAME.a.
//   * We append ".o".

// When using a search path, we apply each of these transformations at
// each entry on the search path before moving on to the next entry.
// If the file exists, but does not contain any Go export data, we
// stop; we do not keep looking for another file with the same name
// later in the search path.

Import::Stream*
Import::open_package(const std::string& filename, Location location,
		     const std::string& relative_import_path)
{
  bool is_local;
  if (IS_ABSOLUTE_PATH(filename))
    is_local = true;
  else if (filename[0] == '.'
	   && (filename[1] == '\0' || IS_DIR_SEPARATOR(filename[1])))
    is_local = true;
  else if (filename[0] == '.'
	   && filename[1] == '.'
	   && (filename[2] == '\0' || IS_DIR_SEPARATOR(filename[2])))
    is_local = true;
  else
    is_local = false;

  std::string fn = filename;
  if (is_local && !IS_ABSOLUTE_PATH(filename) && !relative_import_path.empty())
    {
      if (fn == ".")
	{
	  // A special case.
	  fn = relative_import_path;
	}
      else if (fn[0] == '.' && fn[1] == '.'
	       && (fn[2] == '\0' || IS_DIR_SEPARATOR(fn[2])))
	{
	  // We are going to join relative_import_path and fn, and it
	  // will look like DIR/../PATH.  But DIR does not necessarily
	  // exist in this case, and if it doesn't the use of .. will
	  // fail although it shouldn't.  The gc compiler uses
	  // path.Join here, which cleans up the .., so we need to do
	  // the same.
	  size_t index;
	  for (index = relative_import_path.length() - 1;
	       index > 0 && !IS_DIR_SEPARATOR(relative_import_path[index]);
	       index--)
	    ;
	  if (index > 0)
	    fn = relative_import_path.substr(0, index) + fn.substr(2);
	  else
	    fn = relative_import_path + '/' + fn;
	}
      else
	fn = relative_import_path + '/' + fn;
      is_local = false;
    }

  if (!is_local)
    {
      for (std::vector<std::string>::const_iterator p = search_path.begin();
	   p != search_path.end();
	   ++p)
	{
	  std::string indir = *p;
	  if (!indir.empty() && indir[indir.size() - 1] != '/')
	    indir += '/';
	  indir += fn;
	  Stream* s = Import::try_package_in_directory(indir, location);
	  if (s != NULL)
	    return s;
	}
    }

  Stream* s = Import::try_package_in_directory(fn, location);
  if (s != NULL)
    return s;

  return NULL;
}

// Try to find the export data for FILENAME.

Import::Stream*
Import::try_package_in_directory(const std::string& filename,
				 Location location)
{
  std::string found_filename = filename;
  int fd = open(found_filename.c_str(), O_RDONLY | O_BINARY);

  if (fd >= 0)
    {
      struct stat s;
      if (fstat(fd, &s) >= 0 && S_ISDIR(s.st_mode))
	{
	  close(fd);
	  fd = -1;
	  errno = EISDIR;
	}
    }

  if (fd < 0)
    {
      if (errno != ENOENT && errno != EISDIR)
	go_warning_at(location, 0, "%s: %m", filename.c_str());

      fd = Import::try_suffixes(&found_filename);
      if (fd < 0)
	return NULL;
    }

  // The export data may not be in this file.
  Stream* s = Import::find_export_data(found_filename, fd, location);
  if (s != NULL)
    return s;

  close(fd);

  go_error_at(location, "%s exists but does not contain any Go export data",
	      found_filename.c_str());

  return NULL;
}

// Given import "*PFILENAME", where *PFILENAME does not exist, try
// various suffixes.  If we find one, set *PFILENAME to the one we
// found.  Return the open file descriptor.

int
Import::try_suffixes(std::string* pfilename)
{
  std::string filename = *pfilename + ".gox";
  int fd = open(filename.c_str(), O_RDONLY | O_BINARY);
  if (fd >= 0)
    {
      *pfilename = filename;
      return fd;
    }

  const char* basename = lbasename(pfilename->c_str());
  size_t basename_pos = basename - pfilename->c_str();
  filename = pfilename->substr(0, basename_pos) + "lib" + basename + ".so";
  fd = open(filename.c_str(), O_RDONLY | O_BINARY);
  if (fd >= 0)
    {
      *pfilename = filename;
      return fd;
    }

  filename = pfilename->substr(0, basename_pos) + "lib" + basename + ".a";
  fd = open(filename.c_str(), O_RDONLY | O_BINARY);
  if (fd >= 0)
    {
      *pfilename = filename;
      return fd;
    }

  filename = *pfilename + ".o";
  fd = open(filename.c_str(), O_RDONLY | O_BINARY);
  if (fd >= 0)
    {
      *pfilename = filename;
      return fd;
    }

  return -1;
}

// Look for export data in the file descriptor FD.

Import::Stream*
Import::find_export_data(const std::string& filename, int fd, Location location)
{
  // See if we can read this as an object file.
  Import::Stream* stream = Import::find_object_export_data(filename, fd, 0,
							   location);
  if (stream != NULL)
    return stream;

  const int len = MAX(Export::magic_len, Import::archive_magic_len);

  if (lseek(fd, 0, SEEK_SET) < 0)
    {
      go_error_at(location, "lseek %s failed: %m", filename.c_str());
      return NULL;
    }

  char buf[len];
  ssize_t c = ::read(fd, buf, len);
  if (c < len)
    return NULL;

  // Check for a file containing nothing but Go export data.
  if (memcmp(buf, Export::cur_magic, Export::magic_len) == 0
      || memcmp(buf, Export::v1_magic, Export::magic_len) == 0
      || memcmp(buf, Export::v2_magic, Export::magic_len) == 0)
    return new Stream_from_file(fd);

  // See if we can read this as an archive.
  if (Import::is_archive_magic(buf))
    return Import::find_archive_export_data(filename, fd, location);

  return NULL;
}

// Look for export data in an object file.

Import::Stream*
Import::find_object_export_data(const std::string& filename,
				int fd,
				off_t offset,
				Location location)
{
  char *buf;
  size_t len;
  int err;
  const char *errmsg = go_read_export_data(fd, offset, &buf, &len, &err);
  if (errmsg != NULL)
    {
      if (err == 0)
	go_error_at(location, "%s: %s", filename.c_str(), errmsg);
      else
	go_error_at(location, "%s: %s: %s", filename.c_str(), errmsg,
		    xstrerror(err));
      return NULL;
    }

  if (buf == NULL)
    return NULL;

  return new Stream_from_buffer(buf, len);
}

// Class Import.

// Construct an Import object.  We make the builtin_types_ vector
// large enough to hold all the builtin types.

Import::Import(Stream* stream, Location location)
  : gogo_(NULL), stream_(stream), location_(location), package_(NULL),
    add_to_globals_(false), packages_(), type_data_(), type_pos_(0),
    type_offsets_(), builtin_types_((- SMALLEST_BUILTIN_CODE) + 1),
    types_(), version_(EXPORT_FORMAT_UNKNOWN)
{
}

// Import the data in the associated stream.

Package*
Import::import(Gogo* gogo, const std::string& local_name,
	       bool is_local_name_exported)
{
  // Hold on to the Gogo structure.  Otherwise we need to pass it
  // through all the import functions, because we need it when reading
  // a type.
  this->gogo_ = gogo;

  // A stream of export data can include data from more than one input
  // file.  Here we loop over each input file.
  Stream* stream = this->stream_;
  while (!stream->at_eof() && !stream->saw_error())
    {
      // The vector of types is package specific.
      this->types_.clear();

      // Check magic string / version number.
      if (stream->match_bytes(Export::cur_magic, Export::magic_len))
	{
	  stream->require_bytes(this->location_, Export::cur_magic,
	                        Export::magic_len);
	  this->version_ = EXPORT_FORMAT_CURRENT;
	}
      else if (stream->match_bytes(Export::v1_magic, Export::magic_len))
	{
	  stream->require_bytes(this->location_, Export::v1_magic,
	                        Export::magic_len);
	  this->version_ = EXPORT_FORMAT_V1;
	}
      else if (stream->match_bytes(Export::v2_magic, Export::magic_len))
	{
	  stream->require_bytes(this->location_, Export::v2_magic,
	                        Export::magic_len);
	  this->version_ = EXPORT_FORMAT_V2;
	}
      else
	{
	  go_error_at(this->location_,
		      ("error in import data at %d: invalid magic string"),
		      stream->pos());
	  return NULL;
	}

      this->require_c_string("package ");
      std::string package_name = this->read_identifier();
      this->require_semicolon_if_old_version();
      this->require_c_string("\n");

      std::string pkgpath;
      std::string pkgpath_symbol;
      if (this->match_c_string("prefix "))
	{
	  this->advance(7);
	  std::string unique_prefix = this->read_identifier();
	  this->require_semicolon_if_old_version();
	  this->require_c_string("\n");
	  pkgpath = unique_prefix + '.' + package_name;
	  pkgpath_symbol = (Gogo::pkgpath_for_symbol(unique_prefix) + '.'
			    + Gogo::pkgpath_for_symbol(package_name));
	}
      else
	{
	  this->require_c_string("pkgpath ");
	  pkgpath = this->read_identifier();
	  this->require_semicolon_if_old_version();
	  this->require_c_string("\n");
	  pkgpath_symbol = Gogo::pkgpath_for_symbol(pkgpath);
	}

      if (stream->saw_error())
	return NULL;

      this->package_ = gogo->add_imported_package(package_name, local_name,
						  is_local_name_exported,
						  pkgpath, pkgpath_symbol,
						  this->location_,
						  &this->add_to_globals_);
      if (this->package_ == NULL)
	{
	  stream->set_saw_error();
	  return NULL;
	}

      // Read and discard priority if older V1 export data format.
      if (version() == EXPORT_FORMAT_V1)
	{
	  this->require_c_string("priority ");
	  std::string priority_string = this->read_identifier();
	  int prio;
	  if (!this->string_to_int(priority_string, false, &prio))
	    return NULL;
	  this->require_c_string(";\n");
	}

      while (stream->match_c_string("package"))
	this->read_one_package();

      while (stream->match_c_string("import"))
	this->read_one_import();

      while (stream->match_c_string("indirectimport"))
	this->read_one_indirect_import();

      if (stream->match_c_string("init"))
	this->read_import_init_fns(gogo);

      if (stream->match_c_string("types "))
	{
	  if (!this->read_types())
	    return NULL;
	}

      // Loop over all the input data for this package.
      while (!stream->saw_error())
	{
	  if (stream->match_c_string("const "))
	    this->import_const();
	  else if (stream->match_c_string("type "))
	    this->import_type();
	  else if (stream->match_c_string("var "))
	    this->import_var();
	  else if (stream->match_c_string("func "))
	    this->import_func(this->package_);
	  else if (stream->match_c_string("checksum "))
	    break;
	  else
	    {
	      go_error_at(this->location_,
			  ("error in import data at %d: "
			   "expected %<const%>, %<type%>, %<var%>, "
			   "%<func%>, or %<checksum%>"),
			  stream->pos());
	      stream->set_saw_error();
	      return NULL;
	    }
	}

      // We currently ignore the checksum.  In the future we could
      // store the checksum somewhere in the generated object and then
      // verify that the checksum matches at link time or at dynamic
      // load time.
      this->require_c_string("checksum ");
      stream->advance(Export::checksum_len * 2);
      this->require_semicolon_if_old_version();
      this->require_c_string("\n");
    }

  return this->package_;
}

// Read a package line.  This let us reliably determine the pkgpath
// symbol, even if the package was compiled with a -fgo-prefix option.

void
Import::read_one_package()
{
  this->require_c_string("package ");
  std::string package_name = this->read_identifier();
  this->require_c_string(" ");
  std::string pkgpath = this->read_identifier();
  this->require_c_string(" ");
  std::string pkgpath_symbol = this->read_identifier();
  this->require_semicolon_if_old_version();
  this->require_c_string("\n");

  Package* p = this->gogo_->register_package(pkgpath, pkgpath_symbol,
					     Linemap::unknown_location());
  p->set_package_name(package_name, this->location());
}

// Read an import line.

void
Import::read_one_import()
{
  this->require_c_string("import ");
  std::string package_name = this->read_identifier();
  this->require_c_string(" ");
  std::string pkgpath = this->read_identifier();
  this->require_c_string(" \"");
  Stream* stream = this->stream_;
  while (stream->peek_char() != '"')
    stream->advance(1);
  this->require_c_string("\"");
  this->require_semicolon_if_old_version();
  this->require_c_string("\n");

  Package* p = this->gogo_->register_package(pkgpath, "",
					     Linemap::unknown_location());
  p->set_package_name(package_name, this->location());

  this->packages_.push_back(p);
}

// Read an indirectimport line.

void
Import::read_one_indirect_import()
{
  this->require_c_string("indirectimport ");
  std::string package_name = this->read_identifier();
  this->require_c_string(" ");
  std::string pkgpath = this->read_identifier();
  this->require_c_string("\n");

  Package* p = this->gogo_->register_package(pkgpath, "",
					     Linemap::unknown_location());
  p->set_package_name(package_name, this->location());

  this->packages_.push_back(p);
}

// Read the list of import control functions and/or init graph.

void
Import::read_import_init_fns(Gogo* gogo)
{
  this->require_c_string("init");

  // Maps init function to index in the "init" clause; needed
  // to read the init_graph section.
  std::map<std::string, unsigned> init_idx;

  while (!this->match_c_string("\n") && !this->match_c_string(";"))
    {
      int priority = -1;

      this->require_c_string(" ");
      std::string package_name = this->read_identifier();
      this->require_c_string(" ");
      std::string init_name = this->read_identifier();
      if (this->version_ == EXPORT_FORMAT_V1)
        {
          // Older version 1 init fcn export data format is:
          //
          //   <packname> <fcn> <priority>
          this->require_c_string(" ");
          std::string prio_string = this->read_identifier();
          if (!this->string_to_int(prio_string, false, &priority))
            return;
        }
      gogo->add_import_init_fn(package_name, init_name, priority);

      // Record the index of this init fcn so that we can look it
      // up by index in the subsequent init_graph section.
      unsigned idx = init_idx.size();
      init_idx[init_name] = idx;
    }
  this->require_semicolon_if_old_version();
  this->require_c_string("\n");

  if (this->match_c_string("init_graph"))
    {
      this->require_c_string("init_graph");

      // Build a vector mapping init fcn slot to Import_init pointer.
      go_assert(init_idx.size() > 0);
      std::vector<Import_init*> import_initvec;
      import_initvec.resize(init_idx.size());
      for (std::map<std::string, unsigned>::const_iterator it =
               init_idx.begin();
           it != init_idx.end(); ++it)
	{
	  const std::string& init_name = it->first;
	  Import_init* ii = gogo->lookup_init(init_name);
	  import_initvec[it->second] = ii;
	}

      // Init graph format is:
      //
      //    init_graph <src1> <sink1> <src2> <sink2> ... ;
      //
      // where src + sink are init functions indices.

      while (!this->match_c_string("\n") && !this->match_c_string(";"))
	{
	  this->require_c_string(" ");
	  std::string src_string = this->read_identifier();
	  unsigned src;
	  if (!this->string_to_unsigned(src_string, &src)) return;

	  this->require_c_string(" ");
	  std::string sink_string = this->read_identifier();
	  unsigned sink;
	  if (!this->string_to_unsigned(sink_string, &sink)) return;

	  go_assert(src < import_initvec.size());
	  Import_init* ii_src = import_initvec[src];
	  go_assert(sink < import_initvec.size());
	  Import_init* ii_sink = import_initvec[sink];

	  ii_src->record_precursor_fcn(ii_sink->init_name());
	}
      this->require_semicolon_if_old_version();
      this->require_c_string("\n");
    }
}

// Import the types.  Starting in export format version 3 all the
// types are listed first.

bool
Import::read_types()
{
  this->require_c_string("types ");
  std::string str = this->read_identifier();
  int maxp1;
  if (!this->string_to_int(str, false, &maxp1))
    return false;

  this->require_c_string(" ");
  str = this->read_identifier();
  int exportedp1;
  if (!this->string_to_int(str, false, &exportedp1))
    return false;

  this->type_offsets_.resize(maxp1, std::make_pair<size_t, size_t>(0, 0));
  size_t total_type_size = 0;
  // Start at 1 because type index 0 not used.
  for (int i = 1; i < maxp1; i++)
    {
      this->require_c_string(" ");
      str = this->read_identifier();
      int v;
      if (!this->string_to_int(str, false, &v))
	return false;
      size_t vs = static_cast<size_t>(v);
      this->type_offsets_[i] = std::make_pair(total_type_size, vs);
      total_type_size += vs;
    }

  this->require_c_string("\n");

  // Types can refer to each other in an unpredictable order.  Read
  // all the type data into type_data_.  The type_offsets_ vector we
  // just initialized provides indexes into type_data_.

  this->type_pos_ = this->stream_->pos();
  const char* type_data;
  if (!this->stream_->peek(total_type_size, &type_data))
    return false;
  this->type_data_ = std::string(type_data, total_type_size);
  this->advance(total_type_size);

  this->types_.resize(maxp1, NULL);

  // Parse all the exported types now, so that the names are properly
  // bound and visible to the parser.  Parse unexported types lazily.

  // Start at 1 because there is no type 0.
  for (int i = 1; i < exportedp1; i++)
    {
      // We may have already parsed this type when we parsed an
      // earlier type.
      Type* type = this->types_[i];
      if (type == NULL)
	{
	  if (!this->parse_type(i))
	    return false;
	  type = this->types_[i];
	  go_assert(type != NULL);
	}
      Named_type* nt = type->named_type();
      if (nt == NULL)
	{
	  go_error_at(this->location_,
		      "error in import data: exported unnamed type %d",
		      i);
	  return false;
	}
      nt->set_is_visible();
      if (this->add_to_globals_)
	this->gogo_->add_named_type(nt);
    }

  return true;
}

// Import a constant.

void
Import::import_const()
{
  std::string name;
  Type* type;
  Expression* expr;
  Named_constant::import_const(this, &name, &type, &expr);
  Typed_identifier tid(name, type, this->location_);
  Named_object* no = this->package_->add_constant(tid, expr);
  if (this->add_to_globals_)
    this->gogo_->add_dot_import_object(no);
}

// Import a type.

void
Import::import_type()
{
  if (this->version_ >= EXPORT_FORMAT_V3)
    {
      if (!this->stream_->saw_error())
	{
	  go_error_at(this->location_,
		    "error in import data at %d: old type syntax",
		    this->stream_->pos());
	  this->stream_->set_saw_error();
	}
      return;
    }

  Named_type* type;
  Named_type::import_named_type(this, &type);

  // The named type has been added to the package by the type import
  // process.  Here we need to make it visible to the parser, and it
  // to the global bindings if necessary.
  type->set_is_visible();

  if (this->add_to_globals_)
    this->gogo_->add_named_type(type);
}

// Import a variable.

void
Import::import_var()
{
  std::string name;
  Package* vpkg;
  bool is_exported;
  Type* type;
  if (!Variable::import_var(this, &name, &vpkg, &is_exported, &type))
    return;
  if (vpkg == NULL)
    vpkg = this->package_;
  if (!is_exported)
    name = '.' + vpkg->pkgpath() + '.' + name;
  Variable* var = new Variable(type, NULL, true, false, false,
			       this->location_);
  Named_object* no;
  no = vpkg->add_variable(name, var);
  if (this->add_to_globals_)
    this->gogo_->add_dot_import_object(no);
}

// Import a function into PACKAGE.  PACKAGE is normally
// THIS->PACKAGE_, but it will be different for a method associated
// with a type defined in a different package.

void
Import::import_func(Package* package)
{
  std::string name;
  Package* fpkg;
  bool is_exported;
  Typed_identifier* receiver;
  Typed_identifier_list* parameters;
  Typed_identifier_list* results;
  bool is_varargs;
  bool nointerface;
  std::string asm_name;
  std::string body;
  if (!Function::import_func(this, &name, &fpkg, &is_exported, &receiver,
			     &parameters, &results, &is_varargs, &nointerface,
			     &asm_name, &body))
    return;
  if (fpkg == NULL)
    fpkg = package;
  if (!is_exported)
    name = '.' + fpkg->pkgpath() + '.' + name;
  Function_type *fntype = Type::make_function_type(receiver, parameters,
						   results, this->location_);
  if (is_varargs)
    fntype->set_is_varargs();

  Location loc = this->location_;
  Named_object* no;
  if (fntype->is_method())
    {
      Type* rtype = receiver->type();

      // We may still be reading the definition of RTYPE, so we have
      // to be careful to avoid calling base or convert.  If RTYPE is
      // a named type or a forward declaration, then we know that it
      // is not a pointer, because we are reading a method on RTYPE
      // and named pointers can't have methods.

      if (rtype->classification() == Type::TYPE_POINTER)
	rtype = rtype->points_to();

      if (rtype->is_error_type())
	return;
      else if (rtype->named_type() != NULL)
	no = rtype->named_type()->add_method_declaration(name, fpkg, fntype,
							 loc);
      else if (rtype->forward_declaration_type() != NULL)
	no = rtype->forward_declaration_type()->add_method_declaration(name,
								       fpkg,
								       fntype,
								       loc);
      else
	go_unreachable();
    }
  else
    {
      no = fpkg->add_function_declaration(name, fntype, loc);
      if (this->add_to_globals_ && fpkg == package)
	this->gogo_->add_dot_import_object(no);
    }

  if (nointerface)
    no->func_declaration_value()->set_nointerface();
  if (!asm_name.empty())
    no->func_declaration_value()->set_asm_name(asm_name);
  if (!body.empty() && !no->func_declaration_value()->has_imported_body())
    no->func_declaration_value()->set_imported_body(this, body);
}

// Read a type definition and initialize the entry in this->types_.
// This parses the type definition saved by read_types earlier.  This
// returns true on success, false on failure.

bool
Import::parse_type(int i)
{
  go_assert(i >= 0 && static_cast<size_t>(i) < this->types_.size());
  go_assert(this->types_[i] == NULL);
  size_t offset = this->type_offsets_[i].first;
  size_t len = this->type_offsets_[i].second;

  Stream* orig_stream = this->stream_;

  Stream_from_string_ref stream(this->type_data_, offset, len);
  stream.set_pos(this->type_pos_ + offset);
  this->stream_ = &stream;

  this->require_c_string("type ");
  std::string str = this->read_identifier();
  int id;
  if (!this->string_to_int(str, false, &id))
    {
      this->stream_ = orig_stream;
      return false;
    }
  if (i != id)
    {
      go_error_at(this->location_,
		  ("error in import data at %d: "
		   "type ID mismatch: got %d, want %d"),
		  stream.pos(), id, i);
      this->stream_ = orig_stream;
      return false;
    }

  this->require_c_string(" ");
  if (stream.peek_char() == '"')
    {
      stream.advance(1);
      Type* type = this->read_named_type(i);
      if (type->is_error_type())
	{
	  this->stream_ = orig_stream;
	  return false;
	}
    }
  else
    {
      Type* type = Type::import_type(this);
      if (type->is_error_type())
	{
	  this->stream_ = orig_stream;
	  return false;
	}
      this->types_[i] = type;

      this->require_c_string("\n");
    }

  this->stream_ = orig_stream;
  return true;
}

// Read a type in the import stream.  This records the type by the
// type index.  If the type is named (which can only happen with older
// export formats), it registers the name, but marks it as invisible.

Type*
Import::read_type()
{
  Stream* stream = this->stream_;
  this->require_c_string("<type ");

  std::string number;
  int c;
  while (true)
    {
      c = stream->get_char();
      if (c != '-' && (c < '0' || c > '9'))
	break;
      number += c;
    }

  int index;
  if (!this->string_to_int(number, true, &index))
    return Type::make_error_type();

  if (c == '>')
    {
      // A reference to a type defined earlier.
      bool parsed;
      return this->type_for_index(index, "import data", stream->pos(),
				  &parsed);
    }

  if (this->version_ >= EXPORT_FORMAT_V3)
    {
      if (!stream->saw_error())
	go_error_at(this->location_,
		    "error in import data at %d: expected %<>%>",
		    stream->pos());
      stream->set_saw_error();
      return Type::make_error_type();
    }

  if (c != ' ')
    {
      if (!stream->saw_error())
	go_error_at(this->location_,
		    "error in import data at %d: expected %< %> or %<>%>",
		    stream->pos());
      stream->set_saw_error();
      stream->advance(1);
      return Type::make_error_type();
    }

  if (index <= 0
      || (static_cast<size_t>(index) < this->types_.size()
	  && this->types_[index] != NULL))
    {
      go_error_at(this->location_,
		  "error in import data at %d: type index already defined",
		  stream->pos());
      stream->set_saw_error();
      return Type::make_error_type();
    }

  if (static_cast<size_t>(index) >= this->types_.size())
    {
      int newsize = std::max(static_cast<size_t>(index) + 1,
			     this->types_.size() * 2);
      this->types_.resize(newsize, NULL);
    }

  if (stream->peek_char() != '"')
    {
      Type* type = Type::import_type(this);
      this->require_c_string(">");
      this->types_[index] = type;
      return type;
    }

  stream->advance(1);

  Type* type = this->read_named_type(index);

  this->require_c_string(">");

  return type;
}

// Read a named type from the import stream and store it in
// this->types_[index].  The stream should be positioned immediately
// after the '"' that starts the name.

Type*
Import::read_named_type(int index)
{
  Stream* stream = this->stream_;
  std::string type_name;
  int c;
  while ((c = stream->get_char()) != '"')
    type_name += c;

  // If this type is in the package we are currently importing, the
  // name will be .PKGPATH.NAME or simply NAME with no dots.
  // Otherwise, a non-hidden symbol will be PKGPATH.NAME and a hidden
  // symbol will be .PKGPATH.NAME.
  std::string pkgpath;
  if (type_name.find('.') != std::string::npos)
    {
      size_t start = 0;
      if (type_name[0] == '.')
	start = 1;
      size_t dot = type_name.rfind('.');
      pkgpath = type_name.substr(start, dot - start);
      if (type_name[0] != '.')
	type_name.erase(0, dot + 1);
    }

  this->require_c_string(" ");

  // The package name may follow.  This is the name of the package in
  // the package clause of that package.  The type name will include
  // the pkgpath, which may be different.
  std::string package_name;
  if (stream->peek_char() == '"')
    {
      stream->advance(1);
      while ((c = stream->get_char()) != '"')
	package_name += c;
      this->require_c_string(" ");
    }

  bool is_alias = false;
  if (this->match_c_string("= "))
    {
      stream->advance(2);
      is_alias = true;
    }

  // Declare the type in the appropriate package.  If we haven't seen
  // it before, mark it as invisible.  We declare it before we read
  // the actual definition of the type, since the definition may refer
  // to the type itself.
  Package* package;
  if (pkgpath.empty() || pkgpath == this->gogo_->pkgpath())
    package = this->package_;
  else
    {
      package = this->gogo_->register_package(pkgpath, "",
					      Linemap::unknown_location());
      if (!package_name.empty())
	package->set_package_name(package_name, this->location());
    }

  Named_object* no = package->bindings()->lookup(type_name);
  if (no == NULL)
    no = package->add_type_declaration(type_name, this->location_);
  else if (!no->is_type_declaration() && !no->is_type())
    {
      go_error_at(this->location_, "imported %<%s.%s%> both type and non-type",
		  pkgpath.c_str(), Gogo::message_name(type_name).c_str());
      stream->set_saw_error();
      return Type::make_error_type();
    }
  else
    go_assert(no->package() == package);

  if (this->types_[index] == NULL)
    {
      if (no->is_type_declaration())
	{
	  // FIXME: It's silly to make a forward declaration every time.
	  this->types_[index] = Type::make_forward_declaration(no);
	}
      else
	{
	  go_assert(no->is_type());
	  this->types_[index] = no->type_value();
	}
    }

  // If there is no type definition, then this is just a forward
  // declaration of a type defined in some other file.
  Type* type;
  if (this->match_c_string(">") || this->match_c_string("\n"))
    type = this->types_[index];
  else
    {
      type = this->read_type();

      if (no->is_type_declaration())
	{
	  // We can define the type now.

	  no = package->add_type(type_name, type, this->location_);
	  Named_type* ntype = no->type_value();

	  // This type has not yet been imported.
	  ntype->clear_is_visible();

	  if (is_alias)
	    ntype->set_is_alias();

	  if (!type->is_undefined() && type->interface_type() != NULL)
	    this->gogo_->record_interface_type(type->interface_type());

	  type = ntype;
	}
      else if (no->is_type())
	{
	  // We have seen this type before.  FIXME: it would be a good
	  // idea to check that the two imported types are identical,
	  // but we have not finalized the methods yet, which means
	  // that we can not reliably compare interface types.
	  type = no->type_value();

	  // Don't change the visibility of the existing type.
	}

      this->types_[index] = type;

      // Read the type methods.
      if (this->match_c_string("\n"))
	{
	  this->advance(1);
	  while (this->match_c_string(" func"))
	    {
	      this->advance(1);
	      this->import_func(package);
	    }
	}
    }

  return type;
}

// Return the type given an index.  Set *PARSED if we parsed it here.

Type*
Import::type_for_index(int index, const std::string& input_name,
		       size_t input_offset, bool* parsed)
{
  *parsed = false;
  if (index >= 0 && !this->type_data_.empty())
    {
      if (static_cast<size_t>(index) >= this->type_offsets_.size())
	{
	  go_error_at(this->location_,
		      "error in %s at %lu: bad type index %d, max %d",
		      input_name.c_str(),
		      static_cast<unsigned long>(input_offset),
		      index, static_cast<int>(this->type_offsets_.size()));
	  return Type::make_error_type();
	}

      if (this->types_[index] == NULL)
	{
	  if (!this->parse_type(index))
	    return Type::make_error_type();
	  *parsed = true;
	}
    }

  if (index < 0
      ? (static_cast<size_t>(- index) >= this->builtin_types_.size()
	 || this->builtin_types_[- index] == NULL)
      : (static_cast<size_t>(index) >= this->types_.size()
	 || this->types_[index] == NULL))
    {
      go_error_at(this->location_,
		  "error in %s at %lu: bad type index %d",
		  input_name.c_str(),
		  static_cast<unsigned long>(input_offset), index);
      return Type::make_error_type();
    }

  return index < 0 ? this->builtin_types_[- index] : this->types_[index];
}

// Read an escape note.

std::string
Import::read_escape()
{
  if (this->match_c_string(" <esc:"))
    {
      Stream* stream = this->stream_;
      this->require_c_string(" <esc:");

      std::string escape = "esc:";
      int c;
      while (true)
	{
	  c = stream->get_char();
	  if (c != 'x' && !ISXDIGIT(c))
	    break;
	  escape += c;
	}

      if (c != '>')
	{
	  go_error_at(this->location(),
		      ("error in import data at %d: "
		       "expect %< %> or %<>%>, got %c"),
		      stream->pos(), c);
	  stream->set_saw_error();
	  stream->advance(1);
	  escape = Escape_note::make_tag(Node::ESCAPE_UNKNOWN);
	}
      return escape;
    }
  else
    return Escape_note::make_tag(Node::ESCAPE_UNKNOWN);
}


// Register the builtin types.

void
Import::register_builtin_types(Gogo* gogo)
{
  this->register_builtin_type(gogo, "int8", BUILTIN_INT8);
  this->register_builtin_type(gogo, "int16", BUILTIN_INT16);
  this->register_builtin_type(gogo, "int32", BUILTIN_INT32);
  this->register_builtin_type(gogo, "int64", BUILTIN_INT64);
  this->register_builtin_type(gogo, "uint8", BUILTIN_UINT8);
  this->register_builtin_type(gogo, "uint16", BUILTIN_UINT16);
  this->register_builtin_type(gogo, "uint32", BUILTIN_UINT32);
  this->register_builtin_type(gogo, "uint64", BUILTIN_UINT64);
  this->register_builtin_type(gogo, "float32", BUILTIN_FLOAT32);
  this->register_builtin_type(gogo, "float64", BUILTIN_FLOAT64);
  this->register_builtin_type(gogo, "complex64", BUILTIN_COMPLEX64);
  this->register_builtin_type(gogo, "complex128", BUILTIN_COMPLEX128);
  this->register_builtin_type(gogo, "int", BUILTIN_INT);
  this->register_builtin_type(gogo, "uint", BUILTIN_UINT);
  this->register_builtin_type(gogo, "uintptr", BUILTIN_UINTPTR);
  this->register_builtin_type(gogo, "bool", BUILTIN_BOOL);
  this->register_builtin_type(gogo, "string", BUILTIN_STRING);
  this->register_builtin_type(gogo, "error", BUILTIN_ERROR);
  this->register_builtin_type(gogo, "byte", BUILTIN_BYTE);
  this->register_builtin_type(gogo, "rune", BUILTIN_RUNE);
}

// Register a single builtin type.

void
Import::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code)
{
  Named_object* named_object = gogo->lookup_global(name);
  go_assert(named_object != NULL && named_object->is_type());
  int index = - static_cast<int>(code);
  go_assert(index > 0
	     && static_cast<size_t>(index) < this->builtin_types_.size());
  this->builtin_types_[index] = named_object->type_value();
}

// Characters that stop read_identifier.  We base this on the
// characters that stop an identifier, without worrying about
// characters that are permitted in an identifier.  That lets us skip
// UTF-8 parsing.
static const char * const identifier_stop = " \n;:,()[]";

// Read an identifier from the stream.

std::string
Import::read_identifier()
{
  std::string ret;
  Stream* stream = this->stream_;
  int c;
  while (true)
    {
      c = stream->peek_char();
      if (c == -1 || strchr(identifier_stop, c) != NULL)
	break;

      // FIXME: Probably we shouldn't accept '.', but that might break
      // some existing imports.
      if (c == '.' && stream->match_c_string("..."))
	break;

      ret += c;
      stream->advance(1);
    }
  return ret;
}

// Read a possibly qualified identifier from IMP.  The qualification
// is <pID>, where ID is a package number.  If the name has a leading
// '.', it is not exported; otherwise, it is.  Set *NAME, *PKG and
// *IS_EXPORTED.  Reports whether the read succeeded.

bool
Import::read_qualified_identifier(Import_expression* imp, std::string* name,
				  Package** pkg, bool* is_exported)
{
  *pkg = NULL;
  if (imp->match_c_string("<p"))
    {
      imp->advance(2);
      char buf[50];
      char *pbuf = &buf[0];
      while (true)
	{
	  int next = imp->peek_char();
	  if (next == -1 || static_cast<size_t>(pbuf - buf) >= sizeof buf - 1)
	    return false;
	  if (next == '>')
	    {
	      imp->advance(1);
	      break;
	    }
	  *pbuf = static_cast<char>(next);
	  ++pbuf;
	  imp->advance(1);
	}

      *pbuf = '\0';
      char *end;
      long index = strtol(buf, &end, 10);
      if (*end != '\0'
	  || index <= 0
	  || static_cast<size_t>(index) > imp->max_package_index())
	return false;

      *pkg = imp->package_at_index(index);
      go_assert(*pkg != NULL);
    }

  *is_exported = true;
  if (imp->match_c_string("."))
    {
      imp->advance(1);
      *is_exported = false;
    }

  *name = imp->read_identifier();

  return !name->empty();
}

// Read a name from the stream.

std::string
Import::read_name()
{
  std::string ret = this->read_identifier();
  if (ret == "?")
    ret.clear();
  return ret;
}

// Read LENGTH bytes from the stream.

std::string
Import::read(size_t length)
{
  const char* data;
  if (!this->stream_->peek(length, &data))
    {
      if (!this->stream_->saw_error())
	go_error_at(this->location_, "import error at %d: expected %d bytes",
		    this->stream_->pos(), static_cast<int>(length));
      this->stream_->set_saw_error();
      return "";
    }
  this->advance(length);
  return std::string(data, length);
}

// Turn a string into a integer with appropriate error handling.

bool
Import::string_to_int(const std::string &s, bool is_neg_ok, int* ret)
{
  char* end;
  long prio = strtol(s.c_str(), &end, 10);
  if (*end != '\0' || prio > 0x7fffffff || (prio < 0 && !is_neg_ok))
    {
      go_error_at(this->location_, "invalid integer in import data at %d",
		  this->stream_->pos());
      this->stream_->set_saw_error();
      return false;
    }
  *ret = prio;
  return true;
}

// Class Import::Stream.

Import::Stream::Stream()
  : pos_(0), saw_error_(false)
{
}

Import::Stream::~Stream()
{
}

// Return the next character to come from the stream.

int
Import::Stream::peek_char()
{
  const char* read;
  if (!this->do_peek(1, &read))
    return -1;
  // Make sure we return an unsigned char, so that we don't get
  // confused by \xff.
  unsigned char ret = *read;
  return ret;
}

// Return true if the next LENGTH characters from the stream match
// BYTES

bool
Import::Stream::match_bytes(const char* bytes, size_t length)
{
  const char* read;
  if (!this->do_peek(length, &read))
    return false;
  return memcmp(bytes, read, length) == 0;
}

// Require that the next LENGTH bytes from the stream match BYTES.

void
Import::Stream::require_bytes(Location location, const char* bytes,
			      size_t length)
{
  const char* read;
  if (!this->do_peek(length, &read)
      || memcmp(bytes, read, length) != 0)
    {
      if (!this->saw_error_)
	go_error_at(location, "import error at %d: expected %<%.*s%>",
		    this->pos(), static_cast<int>(length), bytes);
      this->saw_error_ = true;
      return;
    }
  this->advance(length);
}

// Class Stream_from_file.

Stream_from_file::Stream_from_file(int fd)
  : fd_(fd), data_()
{
  if (lseek(fd, 0, SEEK_SET) != 0)
    {
      go_fatal_error(Linemap::unknown_location(), "lseek failed: %m");
      this->set_saw_error();
    }
}

Stream_from_file::~Stream_from_file()
{
  close(this->fd_);
}

// Read next bytes.

bool
Stream_from_file::do_peek(size_t length, const char** bytes)
{
  if (this->data_.length() <= length)
    {
      *bytes = this->data_.data();
      return true;
    }

  this->data_.resize(length);
  ssize_t got = ::read(this->fd_, &this->data_[0], length);

  if (got < 0)
    {
      if (!this->saw_error())
	go_fatal_error(Linemap::unknown_location(), "read failed: %m");
      this->set_saw_error();
      return false;
    }

  if (lseek(this->fd_, - got, SEEK_CUR) != 0)
    {
      if (!this->saw_error())
	go_fatal_error(Linemap::unknown_location(), "lseek failed: %m");
      this->set_saw_error();
      return false;
    }

  if (static_cast<size_t>(got) < length)
    return false;

  *bytes = this->data_.data();
  return true;
}

// Advance.

void
Stream_from_file::do_advance(size_t skip)
{
  if (lseek(this->fd_, skip, SEEK_CUR) != 0)
    {
      if (!this->saw_error())
	go_fatal_error(Linemap::unknown_location(), "lseek failed: %m");
      this->set_saw_error();
    }
  if (!this->data_.empty())
    {
      if (this->data_.length() < skip)
	this->data_.erase(0, skip);
      else
	this->data_.clear();
    }
}

// Class Import_function_body.

// The name of the function we are parsing.

const std::string&
Import_function_body::name() const
{
  return this->named_object_->name();
}

// Class Import_function_body.

// Require that the next bytes match STR, issuing an error if not.
// Advance past the string.

void
Import_function_body::require_c_string(const char* str)
{
  if (!this->match_c_string(str))
    {
      if (!this->saw_error_)
	go_error_at(this->location(),
		    "invalid export data for %qs: expected %qs at %lu",
		    this->name().c_str(), str,
		    static_cast<unsigned long>(this->off_));
      this->saw_error_ = true;
      return;
    }
  this->advance(strlen(str));
}

// Read an identifier.

std::string
Import_function_body::read_identifier()
{
  size_t start = this->off_;
  for (size_t i = start; i < this->body_.length(); i++)
    {
      int c = static_cast<unsigned char>(this->body_[i]);
      if (strchr(identifier_stop, c) != NULL)
	{
	  this->off_ = i;
	  return this->body_.substr(start, i - start);
	}

      // FIXME: Probably we shouldn't accept '.', but that might break
      // some existing imports.
      if (c == '.'
	  && i + 2 < this->body_.length()
	  && this->body_[i + 1] == '.'
	  && this->body_[i + 2] == '.')
	{
	  this->off_ = i;
	  return this->body_.substr(start, i - start);
	}
    }
  this->off_ = this->body_.length();
  return this->body_.substr(start);
}

// Read a type.

Type*
Import_function_body::read_type()
{
  this->require_c_string("<type ");
  size_t start = this->off_;
  size_t i;
  int c = '\0';
  for (i = start; i < this->body_.length(); ++i)
    {
      c = static_cast<unsigned char>(this->body_[i]);
      if (c != '-' && (c < '0' || c > '9'))
	break;
    }
  this->off_ = i + 1;

  char *end;
  std::string num = this->body_.substr(start, i - start);
  long val = strtol(num.c_str(), &end, 10);
  if (*end != '\0' || val > 0x7fffffff)
    {
      if (!this->saw_error_)
	go_error_at(this->location(),
		    "invalid export data for %qs: expected integer at %lu",
		    this->name().c_str(),
		    static_cast<unsigned long>(start));
      this->saw_error_ = true;
      return Type::make_error_type();
    }

  if (c != '>')
    {
      if (!this->saw_error_)
	go_error_at(this->location(),
		    "invalid export data for %qs: expected %<>%> at %lu",
		    this->name().c_str(),
		    static_cast<unsigned long>(i));
      this->saw_error_ = true;
      return Type::make_error_type();
    }

  bool parsed;
  Type* type = this->imp_->type_for_index(static_cast<int>(val), this->name(),
					  static_cast<unsigned long>(start),
					  &parsed);

  // If we just read this type's information, its methods will not
  // have been finalized.  Do that now.
  if (parsed)
    this->gogo_->finalize_methods_for_type(type);

  return type;
}

// Return the next size to use for a vector mapping indexes to values.

size_t
Import_function_body::next_size(size_t have)
{
  if (have == 0)
    return 8;
  else if (have < 256)
    return have * 2;
  else
    return have + 64;
}

// Record the index of a temporary statement.

void
Import_function_body::record_temporary(Temporary_statement* temp,
				       unsigned int idx)
{
  size_t have = this->temporaries_.size();
  while (static_cast<size_t>(idx) >= have)
    {
      size_t want = Import_function_body::next_size(have);
      this->temporaries_.resize(want, NULL);
      have = want;
    }
  this->temporaries_[idx] = temp;
}

// Return a temporary statement given an index.

Temporary_statement*
Import_function_body::temporary_statement(unsigned int idx)
{
  if (static_cast<size_t>(idx) >= this->temporaries_.size())
    return NULL;
  return this->temporaries_[idx];
}

// Return an unnamed label given an index, defining the label if we
// haven't seen it already.

Unnamed_label*
Import_function_body::unnamed_label(unsigned int idx, Location loc)
{
  size_t have = this->labels_.size();
  while (static_cast<size_t>(idx) >= have)
    {
      size_t want = Import_function_body::next_size(have);
      this->labels_.resize(want, NULL);
      have = want;
    }
  Unnamed_label* label = this->labels_[idx];
  if (label == NULL)
    {
      label = new Unnamed_label(loc);
      this->labels_[idx] = label;
    }
  return label;
}
