1 // import.h -- Go frontend import declarations. -*- C++ -*- 2 3 // Copyright 2009 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 #ifndef GO_IMPORT_H 8 #define GO_IMPORT_H 9 10 #include "export.h" 11 #include "go-linemap.h" 12 13 class Gogo; 14 class Package; 15 class Type; 16 class Named_object; 17 class Named_type; 18 class Expression; 19 20 // This class manages importing Go declarations. 21 22 class Import 23 { 24 public: 25 // The Stream class is an interface used to read the data. The 26 // caller should instantiate a child of this class. 27 class Stream 28 { 29 public: 30 Stream(); 31 virtual ~Stream(); 32 33 // Return whether we have seen an error. 34 bool saw_error()35 saw_error() const 36 { return this->saw_error_; } 37 38 // Record that we've seen an error. 39 void set_saw_error()40 set_saw_error() 41 { this->saw_error_ = true; } 42 43 // Return the next character (a value from 0 to 0xff) without 44 // advancing. Returns -1 at end of stream. 45 int 46 peek_char(); 47 48 // Look for LENGTH characters, setting *BYTES to point to them. 49 // Returns false if the bytes are not available. Does not 50 // advance. 51 bool peek(size_t length,const char ** bytes)52 peek(size_t length, const char** bytes) 53 { return this->do_peek(length, bytes); } 54 55 // Return the next character (a value from 0 to 0xff) and advance 56 // the read position by 1. Returns -1 at end of stream. 57 int get_char()58 get_char() 59 { 60 int c = this->peek_char(); 61 this->advance(1); 62 return c; 63 } 64 65 // Return true if at the end of the stream. 66 bool at_eof()67 at_eof() 68 { return this->peek_char() == -1; } 69 70 // Return true if the next bytes match STR. 71 bool match_c_string(const char * str)72 match_c_string(const char* str) 73 { return this->match_bytes(str, strlen(str)); } 74 75 // Return true if the next LENGTH bytes match BYTES. 76 bool 77 match_bytes(const char* bytes, size_t length); 78 79 // Give an error if the next bytes do not match STR. Advance the 80 // read position by the length of STR. 81 void require_c_string(Location location,const char * str)82 require_c_string(Location location, const char* str) 83 { this->require_bytes(location, str, strlen(str)); } 84 85 // Given an error if the next LENGTH bytes do not match BYTES. 86 // Advance the read position by LENGTH. 87 void 88 require_bytes(Location, const char* bytes, size_t length); 89 90 // Advance the read position by SKIP bytes. 91 void advance(size_t skip)92 advance(size_t skip) 93 { 94 this->do_advance(skip); 95 this->pos_ += skip; 96 } 97 98 // Return the current read position. This returns int because it 99 // is more convenient in error reporting. FIXME. 100 int pos()101 pos() 102 { return static_cast<int>(this->pos_); } 103 104 protected: 105 // This function should set *BYTES to point to a buffer holding 106 // the LENGTH bytes at the current read position. It should 107 // return false if the bytes are not available. This should not 108 // change the current read position. 109 virtual bool 110 do_peek(size_t length, const char** bytes) = 0; 111 112 // This function should advance the current read position LENGTH 113 // bytes. 114 virtual void 115 do_advance(size_t skip) = 0; 116 117 private: 118 // The current read position. 119 size_t pos_; 120 // True if we've seen an error reading from this stream. 121 bool saw_error_; 122 }; 123 124 // Find import data. This searches the file system for FILENAME and 125 // returns a pointer to a Stream object to read the data that it 126 // exports. LOCATION is the location of the import statement. 127 // RELATIVE_IMPORT_PATH is used as a prefix for a relative import. 128 static Stream* 129 open_package(const std::string& filename, Location location, 130 const std::string& relative_import_path); 131 132 // Constructor. 133 Import(Stream*, Location); 134 135 // Register the builtin types. 136 void 137 register_builtin_types(Gogo*); 138 139 // Import everything defined in the stream. LOCAL_NAME is the local 140 // name to be used for bindings; if it is the string "." then 141 // bindings should be inserted in the global scope. If LOCAL_NAME 142 // is the empty string then the name of the package itself is the 143 // local name. This returns the imported package, or NULL on error. 144 Package* 145 import(Gogo*, const std::string& local_name, bool is_local_name_exported); 146 147 // The location of the import statement. 148 Location location()149 location() const 150 { return this->location_; } 151 152 // Return the next character. 153 int peek_char()154 peek_char() 155 { return this->stream_->peek_char(); } 156 157 // Return the next character and advance. 158 int get_char()159 get_char() 160 { return this->stream_->get_char(); } 161 162 // Return true at the end of the stream. 163 bool at_eof()164 at_eof() 165 { return this->stream_->at_eof(); } 166 167 // Return whether the next bytes match STR. 168 bool match_c_string(const char * str)169 match_c_string(const char* str) 170 { return this->stream_->match_c_string(str); } 171 172 // Require that the next bytes match STR. 173 void require_c_string(const char * str)174 require_c_string(const char* str) 175 { this->stream_->require_c_string(this->location_, str); } 176 177 // Advance the stream SKIP bytes. 178 void advance(size_t skip)179 advance(size_t skip) 180 { this->stream_->advance(skip); } 181 182 // Read an identifier. 183 std::string 184 read_identifier(); 185 186 // Read a name. This is like read_identifier, except that a "?" is 187 // returned as an empty string. This matches Export::write_name. 188 std::string 189 read_name(); 190 191 // Read a type. 192 Type* 193 read_type(); 194 195 private: 196 static Stream* 197 try_package_in_directory(const std::string&, Location); 198 199 static int 200 try_suffixes(std::string*); 201 202 static Stream* 203 find_export_data(const std::string& filename, int fd, Location); 204 205 static Stream* 206 find_object_export_data(const std::string& filename, int fd, 207 off_t offset, Location); 208 209 static const int archive_magic_len = 8; 210 211 static bool 212 is_archive_magic(const char*); 213 214 static Stream* 215 find_archive_export_data(const std::string& filename, int fd, 216 Location); 217 218 // Read an import line. 219 void 220 read_one_import(); 221 222 // Read the import control functions. 223 void 224 read_import_init_fns(Gogo*); 225 226 // Import a constant. 227 void 228 import_const(); 229 230 // Import a type. 231 void 232 import_type(); 233 234 // Import a variable. 235 void 236 import_var(); 237 238 // Import a function. 239 Named_object* 240 import_func(Package*); 241 242 // Register a single builtin type. 243 void 244 register_builtin_type(Gogo*, const char* name, Builtin_code); 245 246 // Get an integer from a string. 247 bool 248 string_to_int(const std::string&, bool is_neg_ok, int* ret); 249 250 // The general IR. 251 Gogo* gogo_; 252 // The stream from which to read import data. 253 Stream* stream_; 254 // The location of the import statement we are processing. 255 Location location_; 256 // The package we are importing. 257 Package* package_; 258 // Whether to add new objects to the global scope, rather than to a 259 // package scope. 260 bool add_to_globals_; 261 // Mapping from negated builtin type codes to Type structures. 262 std::vector<Named_type*> builtin_types_; 263 // Mapping from exported type codes to Type structures. 264 std::vector<Type*> types_; 265 }; 266 267 // Read import data from a string. 268 269 class Stream_from_string : public Import::Stream 270 { 271 public: Stream_from_string(const std::string & str)272 Stream_from_string(const std::string& str) 273 : str_(str), pos_(0) 274 { } 275 276 protected: 277 bool do_peek(size_t length,const char ** bytes)278 do_peek(size_t length, const char** bytes) 279 { 280 if (this->pos_ + length > this->str_.length()) 281 return false; 282 *bytes = this->str_.data() + this->pos_; 283 return true; 284 } 285 286 void do_advance(size_t len)287 do_advance(size_t len) 288 { this->pos_ += len; } 289 290 private: 291 // The string of data we are reading. 292 std::string str_; 293 // The current position within the string. 294 size_t pos_; 295 }; 296 297 // Read import data from a buffer allocated using malloc. 298 299 class Stream_from_buffer : public Import::Stream 300 { 301 public: Stream_from_buffer(char * buf,size_t length)302 Stream_from_buffer(char* buf, size_t length) 303 : buf_(buf), length_(length), pos_(0) 304 { } 305 ~Stream_from_buffer()306 ~Stream_from_buffer() 307 { free(this->buf_); } 308 309 protected: 310 bool do_peek(size_t length,const char ** bytes)311 do_peek(size_t length, const char** bytes) 312 { 313 if (this->pos_ + length > this->length_) 314 return false; 315 *bytes = this->buf_ + this->pos_; 316 return true; 317 } 318 319 void do_advance(size_t len)320 do_advance(size_t len) 321 { this->pos_ += len; } 322 323 private: 324 // The data we are reading. 325 char* buf_; 326 // The length of the buffer. 327 size_t length_; 328 // The current position within the buffer. 329 size_t pos_; 330 }; 331 332 // Read import data from an open file descriptor. 333 334 class Stream_from_file : public Import::Stream 335 { 336 public: 337 Stream_from_file(int fd); 338 339 ~Stream_from_file(); 340 341 protected: 342 bool 343 do_peek(size_t, const char**); 344 345 void 346 do_advance(size_t); 347 348 private: 349 // No copying. 350 Stream_from_file(const Stream_from_file&); 351 Stream_from_file& operator=(const Stream_from_file&); 352 353 // The file descriptor. 354 int fd_; 355 // Data read from the file. 356 std::string data_; 357 }; 358 359 #endif // !defined(GO_IMPORT_H) 360