diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/go/gofrontend/import.h | |
download | cbb-gcc-4.6.4-upstream.tar.bz2 cbb-gcc-4.6.4-upstream.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'gcc/go/gofrontend/import.h')
-rw-r--r-- | gcc/go/gofrontend/import.h | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/gcc/go/gofrontend/import.h b/gcc/go/gofrontend/import.h new file mode 100644 index 000000000..0101a40c9 --- /dev/null +++ b/gcc/go/gofrontend/import.h @@ -0,0 +1,351 @@ +// 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" + +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(source_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(source_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, source_location location); + + // Constructor. + Import(Stream*, source_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. + source_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 type. + Type* + read_type(); + + // The name used for parameters, receivers, and results in imported + // function types. + static const char* const import_marker; + + private: + static Stream* + try_package_in_directory(const std::string&, source_location); + + static int + try_suffixes(std::string*); + + static Stream* + find_export_data(const std::string& filename, int fd, source_location); + + static Stream* + find_object_export_data(const std::string& filename, int fd, + off_t offset, source_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, + source_location); + + // 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. + source_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 an allocated buffer. + +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() + { delete[] 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) |