aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/go/gofrontend/import.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/go/gofrontend/import.h')
-rw-r--r--gcc-4.9/gcc/go/gofrontend/import.h364
1 files changed, 364 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/go/gofrontend/import.h b/gcc-4.9/gcc/go/gofrontend/import.h
new file mode 100644
index 000000000..9917937e4
--- /dev/null
+++ b/gcc-4.9/gcc/go/gofrontend/import.h
@@ -0,0 +1,364 @@
+// 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();
+
+ 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)