diff gcc/go/gofrontend/import.h @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/go/gofrontend/import.h	Fri Oct 27 22:46:09 2017 +0900
@@ -0,0 +1,389 @@
+// import.h -- Go frontend import declarations.     -*- C++ -*-
+
+// 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.
+
+#ifndef GO_IMPORT_H
+#define GO_IMPORT_H
+
+#include "export.h"
+#include "go-linemap.h"
+
+class Gogo;
+class Package;
+class Type;
+class Named_object;
+class Named_type;
+class Expression;
+
+// This class manages importing Go declarations.
+
+class Import
+{
+ public:
+  // The Stream class is an interface used to read the data.  The
+  // caller should instantiate a child of this class.
+  class Stream
+  {
+   public:
+    Stream();
+    virtual ~Stream();
+
+    // Return whether we have seen an error.
+    bool
+    saw_error() const
+    { return this->saw_error_; }
+
+    // Record that we've seen an error.
+    void
+    set_saw_error()
+    { this->saw_error_ = true; }
+
+    // Return the next character (a value from 0 to 0xff) without
+    // advancing.  Returns -1 at end of stream.
+    int
+    peek_char();
+
+    // Look for LENGTH characters, setting *BYTES to point to them.
+    // Returns false if the bytes are not available.  Does not
+    // advance.
+    bool
+    peek(size_t length, const char** bytes)
+    { return this->do_peek(length, bytes); }
+
+    // Return the next character (a value from 0 to 0xff) and advance
+    // the read position by 1.  Returns -1 at end of stream.
+    int
+    get_char()
+    {
+      int c = this->peek_char();
+      this->advance(1);
+      return c;
+    }
+
+    // Return true if at the end of the stream.
+    bool
+    at_eof()
+    { return this->peek_char() == -1; }
+
+    // Return true if the next bytes match STR.
+    bool
+    match_c_string(const char* str)
+    { return this->match_bytes(str, strlen(str)); }
+
+    // Return true if the next LENGTH bytes match BYTES.
+    bool
+    match_bytes(const char* bytes, size_t length);
+
+    // Give an error if the next bytes do not match STR.  Advance the
+    // read position by the length of STR.
+    void
+    require_c_string(Location location, const char* str)
+    { this->require_bytes(location, str, strlen(str)); }
+
+    // Given an error if the next LENGTH bytes do not match BYTES.
+    // Advance the read position by LENGTH.
+    void
+    require_bytes(Location, const char* bytes, size_t length);
+
+    // Advance the read position by SKIP bytes.
+    void
+    advance(size_t skip)
+    {
+      this->do_advance(skip);
+      this->pos_ += skip;
+    }
+
+    // Return the current read position.  This returns int because it
+    // is more convenient in error reporting.  FIXME.
+    int
+    pos()
+    { return static_cast<int>(this->pos_); }
+
+   protected:
+    // This function should set *BYTES to point to a buffer holding
+    // the LENGTH bytes at the current read position.  It should
+    // return false if the bytes are not available.  This should not
+    // change the current read position.
+    virtual bool
+    do_peek(size_t length, const char** bytes) = 0;
+
+    // This function should advance the current read position LENGTH
+    // bytes.
+    virtual void
+    do_advance(size_t skip) = 0;
+
+   private:
+    // The current read position.
+    size_t pos_;
+    // True if we've seen an error reading from this stream.
+    bool saw_error_;
+  };
+
+  // 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.  LOCATION is the location of the import statement.
+  // RELATIVE_IMPORT_PATH is used as a prefix for a relative import.
+  static Stream*
+  open_package(const std::string& filename, Location location,
+	       const std::string& relative_import_path);
+
+  // Constructor.
+  Import(Stream*, Location);
+
+  // Register the builtin types.
+  void
+  register_builtin_types(Gogo*);
+
+  // Import everything defined in the stream.  LOCAL_NAME is the local
+  // name to be used for bindings; if it is the string "." then
+  // bindings should be inserted in the global scope.  If LOCAL_NAME
+  // is the empty string then the name of the package itself is the
+  // local name.  This returns the imported package, or NULL on error.
+  Package*
+  import(Gogo*, const std::string& local_name, bool is_local_name_exported);
+
+  // The location of the import statement.
+  Location
+  location() const
+  { return this->location_; }
+
+  // Return the package we are importing.
+  Package*
+  package() const
+  { return this->package_; }
+
+  // Return the next character.
+  int
+  peek_char()
+  { return this->stream_->peek_char(); }
+
+  // Return the next character and advance.
+  int
+  get_char()
+  { return this->stream_->get_char(); }
+
+  // Return true at the end of the stream.
+  bool
+  at_eof()
+  { return this->stream_->at_eof(); }
+
+  // Return whether the next bytes match STR.
+  bool
+  match_c_string(const char* str)
+  { return this->stream_->match_c_string(str); }
+
+  // Require that the next bytes match STR.
+  void
+  require_c_string(const char* str)
+  { this->stream_->require_c_string(this->location_, str); }
+
+  // Advance the stream SKIP bytes.
+  void
+  advance(size_t skip)
+  { this->stream_->advance(skip); }
+
+  // Read an identifier.
+  std::string
+  read_identifier();
+
+  // Read a name.  This is like read_identifier, except that a "?" is
+  // returned as an empty string.  This matches Export::write_name.
+  std::string
+  read_name();
+
+  // Read a type.
+  Type*
+  read_type();
+
+  // Read an escape note.
+  std::string
+  read_escape();
+
+ private:
+  static Stream*
+  try_package_in_directory(const std::string&, Location);
+
+  static int
+  try_suffixes(std::string*);
+
+  static Stream*
+  find_export_data(const std::string& filename, int fd, Location);
+
+  static Stream*
+  find_object_export_data(const std::string& filename, int fd,
+			  off_t offset, Location);
+
+  static const int archive_magic_len = 8;
+
+  static bool
+  is_archive_magic(const char*);
+
+  static Stream*
+  find_archive_export_data(const std::string& filename, int fd,
+			   Location);
+
+  // Read a package line.
+  void
+  read_one_package();
+
+  // Read an import line.
+  void
+  read_one_import();
+
+  // Read the import control functions and init graph.
+  void
+  read_import_init_fns(Gogo*);
+
+  // Import a constant.
+  void
+  import_const();
+
+  // Import a type.
+  void
+  import_type();
+
+  // Import a variable.
+  void
+  import_var();
+
+  // Import a function.
+  Named_object*
+  import_func(Package*);
+
+  // Register a single builtin type.
+  void
+  register_builtin_type(Gogo*, const char* name, Builtin_code);
+
+  // Get an integer from a string.
+  bool
+  string_to_int(const std::string&, bool is_neg_ok, int* ret);
+
+  // Get an unsigned integer from a string.
+  bool
+  string_to_unsigned(const std::string& s, unsigned* ret)
+  {
+    int ivalue;
+    if (!this->string_to_int(s, false, &ivalue))
+      return false;
+    *ret = static_cast<unsigned>(ivalue);
+    return true;
+  }
+
+  // Return the version number of the export data we're reading.
+  Export_data_version
+  version() const { return this->version_; }
+
+  // The general IR.
+  Gogo* gogo_;
+  // The stream from which to read import data.
+  Stream* stream_;
+  // The location of the import statement we are processing.
+  Location location_;
+  // The package we are importing.
+  Package* package_;
+  // Whether to add new objects to the global scope, rather than to a
+  // package scope.
+  bool add_to_globals_;
+  // Mapping from negated builtin type codes to Type structures.
+  std::vector<Named_type*> builtin_types_;
+  // Mapping from exported type codes to Type structures.
+  std::vector<Type*> types_;
+  // Version of export data we're reading.
+  Export_data_version version_;
+};
+
+// Read import data from a string.
+
+class Stream_from_string : public Import::Stream
+{
+ public:
+  Stream_from_string(const std::string& str)
+    : str_(str), pos_(0)
+  { }
+
+ protected:
+  bool
+  do_peek(size_t length, const char** bytes)
+  {
+    if (this->pos_ + length > this->str_.length())
+      return false;
+    *bytes = this->str_.data() + this->pos_;
+    return true;
+  }
+
+  void
+  do_advance(size_t len)
+  { this->pos_ += len; }
+
+ private:
+  // The string of data we are reading.
+  std::string str_;
+  // The current position within the string.
+  size_t pos_;
+};
+
+// Read import data from a buffer allocated using malloc.
+
+class Stream_from_buffer : public Import::Stream
+{
+ public:
+  Stream_from_buffer(char* buf, size_t length)
+    : buf_(buf), length_(length), pos_(0)
+  { }
+
+  ~Stream_from_buffer()
+  { free(this->buf_); }
+
+ protected:
+  bool
+  do_peek(size_t length, const char** bytes)
+  {
+    if (this->pos_ + length > this->length_)
+      return false;
+    *bytes = this->buf_ + this->pos_;
+    return true;
+  }
+
+  void
+  do_advance(size_t len)
+  { this->pos_ += len; }
+
+ private:
+  // The data we are reading.
+  char* buf_;
+  // The length of the buffer.
+  size_t length_;
+  // The current position within the buffer.
+  size_t pos_;
+};
+
+// Read import data from an open file descriptor.
+
+class Stream_from_file : public Import::Stream
+{
+ public:
+  Stream_from_file(int fd);
+
+  ~Stream_from_file();
+
+ protected:
+  bool
+  do_peek(size_t, const char**);
+
+  void
+  do_advance(size_t);
+
+ private:
+  // No copying.
+  Stream_from_file(const Stream_from_file&);
+  Stream_from_file& operator=(const Stream_from_file&);
+
+  // The file descriptor.
+  int fd_;
+  // Data read from the file.
+  std::string data_;
+};
+
+#endif // !defined(GO_IMPORT_H)