// 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_(), finalizer_(NULL), version_(EXPORT_FORMAT_UNKNOWN)
{
}

Import::~Import()
{
  if (this->finalizer_ != NULL)
    delete this->finalizer_;
}

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

  // Finalize methods for any imported types. This call is made late in the
  // import process so as to A) avoid finalization of a type whose methods
  // refer to types that are only partially read in, and B) capture both the
  // types imported by read_types() directly, and those imported indirectly
  // because they are referenced by an imported function or variable.
  // See issues #33013 and #33219 for more on why this is needed.
  this->finalize_methods();

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

void
Import::finalize_methods()
{
  if (this->finalizer_ == NULL)
    this->finalizer_ = new Finalize_methods(gogo_);
  Unordered_set(Type*) real_for_named;
  for (size_t i = 1; i < this->types_.size(); i++)
    {
      Type* type = this->types_[i];
      if (type != NULL && type->named_type() != NULL)
        {
          this->finalizer_->type(type);
          real_for_named.insert(type->named_type()->real_type());
        }
    }
  for (size_t i = 1; i < this->types_.size(); i++)
    {
      Type* type = this->types_[i];
      if (type != NULL
          && type->named_type() == NULL
          && real_for_named.find(type) == real_for_named.end())
        this->finalizer_->type(type);
    }
}

// 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.

Import_function_body::Import_function_body(Gogo* gogo,
                                           Import* imp,
                                           Named_object* named_object,
                                           const std::string& body,
                                           size_t off,
                                           Block* block,
                                           int indent)
    : gogo_(gogo), imp_(imp), named_object_(named_object), body_(body),
      off_(off), indent_(indent), temporaries_(), labels_(),
      saw_error_(false)
{
  this->blocks_.push_back(block);
}

Import_function_body::~Import_function_body()
{
  // At this point we should be left with the original outer block only.
  go_assert(saw_errors() || this->blocks_.size() == 1);
}

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