OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [go/] [gofrontend/] [import.h] - Rev 768

Go to most recent revision | Compare with Previous | Blame | View Log

// 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.
  static Stream*
  open_package(const std::string& filename, Location location);
 
  // 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 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();
 
 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 an import line.
  void
  read_one_import();
 
  // Read the import control functions.
  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);
 
  // 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_;
};
 
// 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)
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.