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 13class Gogo; 14class Package; 15class Type; 16class Named_object; 17class Named_type; 18class Expression; 19 20// This class manages importing Go declarations. 21 22class 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 35 saw_error() const 36 { return this->saw_error_; } 37 38 // Record that we've seen an error. 39 void 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 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 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 67 at_eof() 68 { return this->peek_char() == -1; } 69 70 // Return true if the next bytes match STR. 71 bool 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 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 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 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 149 location() const 150 { return this->location_; } 151 152 // Return the package we are importing. 153 Package* 154 package() const 155 { return this->package_; } 156 157 // Return the next character. 158 int 159 peek_char() 160 { return this->stream_->peek_char(); } 161 162 // Return the next character and advance. 163 int 164 get_char() 165 { return this->stream_->get_char(); } 166 167 // Return true at the end of the stream. 168 bool 169 at_eof() 170 { return this->stream_->at_eof(); } 171 172 // Return whether the next bytes match STR. 173 bool 174 match_c_string(const char* str) 175 { return this->stream_->match_c_string(str); } 176 177 // Require that the next bytes match STR. 178 void 179 require_c_string(const char* str) 180 { this->stream_->require_c_string(this->location_, str); } 181 182 // Advance the stream SKIP bytes. 183 void 184 advance(size_t skip) 185 { this->stream_->advance(skip); } 186 187 // Read an identifier. 188 std::string 189 read_identifier(); 190 191 // Read a name. This is like read_identifier, except that a "?" is 192 // returned as an empty string. This matches Export::write_name. 193 std::string 194 read_name(); 195 196 // Read a type. 197 Type* 198 read_type(); 199 200 private: 201 static Stream* 202 try_package_in_directory(const std::string&, Location); 203 204 static int 205 try_suffixes(std::string*); 206 207 static Stream* 208 find_export_data(const std::string& filename, int fd, Location); 209 210 static Stream* 211 find_object_export_data(const std::string& filename, int fd, 212 off_t offset, Location); 213 214 static const int archive_magic_len = 8; 215 216 static bool 217 is_archive_magic(const char*); 218 219 static Stream* 220 find_archive_export_data(const std::string& filename, int fd, 221 Location); 222 223 // Read a package line. 224 void 225 read_one_package(); 226 227 // Read an import line. 228 void 229 read_one_import(); 230 231 // Read the import control functions. 232 void 233 read_import_init_fns(Gogo*); 234 235 // Import a constant. 236 void 237 import_const(); 238 239 // Import a type. 240 void 241 import_type(); 242 243 // Import a variable. 244 void 245 import_var(); 246 247 // Import a function. 248 Named_object* 249 import_func(Package*); 250 251 // Register a single builtin type. 252 void 253 register_builtin_type(Gogo*, const char* name, Builtin_code); 254 255 // Get an integer from a string. 256 bool 257 string_to_int(const std::string&, bool is_neg_ok, int* ret); 258 259 // The general IR. 260 Gogo* gogo_; 261 // The stream from which to read import data. 262 Stream* stream_; 263 // The location of the import statement we are processing. 264 Location location_; 265 // The package we are importing. 266 Package* package_; 267 // Whether to add new objects to the global scope, rather than to a 268 // package scope. 269 bool add_to_globals_; 270 // Mapping from negated builtin type codes to Type structures. 271 std::vector<Named_type*> builtin_types_; 272 // Mapping from exported type codes to Type structures. 273 std::vector<Type*> types_; 274}; 275 276// Read import data from a string. 277 278class Stream_from_string : public Import::Stream 279{ 280 public: 281 Stream_from_string(const std::string& str) 282 : str_(str), pos_(0) 283 { } 284 285 protected: 286 bool 287 do_peek(size_t length, const char** bytes) 288 { 289 if (this->pos_ + length > this->str_.length()) 290 return false; 291 *bytes = this->str_.data() + this->pos_; 292 return true; 293 } 294 295 void 296 do_advance(size_t len) 297 { this->pos_ += len; } 298 299 private: 300 // The string of data we are reading. 301 std::string str_; 302 // The current position within the string. 303 size_t pos_; 304}; 305 306// Read import data from a buffer allocated using malloc. 307 308class Stream_from_buffer : public Import::Stream 309{ 310 public: 311 Stream_from_buffer(char* buf, size_t length) 312 : buf_(buf), length_(length), pos_(0) 313 { } 314 315 ~Stream_from_buffer() 316 { free(this->buf_); } 317 318 protected: 319 bool 320 do_peek(size_t length, const char** bytes) 321 { 322 if (this->pos_ + length > this->length_) 323 return false; 324 *bytes = this->buf_ + this->pos_; 325 return true; 326 } 327 328 void 329 do_advance(size_t len) 330 { this->pos_ += len; } 331 332 private: 333 // The data we are reading. 334 char* buf_; 335 // The length of the buffer. 336 size_t length_; 337 // The current position within the buffer. 338 size_t pos_; 339}; 340 341// Read import data from an open file descriptor. 342 343class Stream_from_file : public Import::Stream 344{ 345 public: 346 Stream_from_file(int fd); 347 348 ~Stream_from_file(); 349 350 protected: 351 bool 352 do_peek(size_t, const char**); 353 354 void 355 do_advance(size_t); 356 357 private: 358 // No copying. 359 Stream_from_file(const Stream_from_file&); 360 Stream_from_file& operator=(const Stream_from_file&); 361 362 // The file descriptor. 363 int fd_; 364 // Data read from the file. 365 std::string data_; 366}; 367 368#endif // !defined(GO_IMPORT_H) 369