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 package we are importing.
153   Package*
package()154   package() const
155   { return this->package_; }
156 
157   // Return the next character.
158   int
peek_char()159   peek_char()
160   { return this->stream_->peek_char(); }
161 
162   // Return the next character and advance.
163   int
get_char()164   get_char()
165   { return this->stream_->get_char(); }
166 
167   // Return true at the end of the stream.
168   bool
at_eof()169   at_eof()
170   { return this->stream_->at_eof(); }
171 
172   // Return whether the next bytes match STR.
173   bool
match_c_string(const char * str)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
require_c_string(const char * str)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
advance(size_t skip)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   // Read an escape note.
201   std::string
202   read_escape();
203 
204  private:
205   static Stream*
206   try_package_in_directory(const std::string&, Location);
207 
208   static int
209   try_suffixes(std::string*);
210 
211   static Stream*
212   find_export_data(const std::string& filename, int fd, Location);
213 
214   static Stream*
215   find_object_export_data(const std::string& filename, int fd,
216 			  off_t offset, Location);
217 
218   static const int archive_magic_len = 8;
219 
220   static bool
221   is_archive_magic(const char*);
222 
223   static Stream*
224   find_archive_export_data(const std::string& filename, int fd,
225 			   Location);
226 
227   // Read a package line.
228   void
229   read_one_package();
230 
231   // Read an import line.
232   void
233   read_one_import();
234 
235   // Read the import control functions and init graph.
236   void
237   read_import_init_fns(Gogo*);
238 
239   // Import a constant.
240   void
241   import_const();
242 
243   // Import a type.
244   void
245   import_type();
246 
247   // Import a variable.
248   void
249   import_var();
250 
251   // Import a function.
252   Named_object*
253   import_func(Package*);
254 
255   // Register a single builtin type.
256   void
257   register_builtin_type(Gogo*, const char* name, Builtin_code);
258 
259   // Get an integer from a string.
260   bool
261   string_to_int(const std::string&, bool is_neg_ok, int* ret);
262 
263   // Get an unsigned integer from a string.
264   bool
string_to_unsigned(const std::string & s,unsigned * ret)265   string_to_unsigned(const std::string& s, unsigned* ret)
266   {
267     int ivalue;
268     if (!this->string_to_int(s, false, &ivalue))
269       return false;
270     *ret = static_cast<unsigned>(ivalue);
271     return true;
272   }
273 
274   // Return the version number of the export data we're reading.
275   Export_data_version
version()276   version() const { return this->version_; }
277 
278   // The general IR.
279   Gogo* gogo_;
280   // The stream from which to read import data.
281   Stream* stream_;
282   // The location of the import statement we are processing.
283   Location location_;
284   // The package we are importing.
285   Package* package_;
286   // Whether to add new objects to the global scope, rather than to a
287   // package scope.
288   bool add_to_globals_;
289   // Mapping from negated builtin type codes to Type structures.
290   std::vector<Named_type*> builtin_types_;
291   // Mapping from exported type codes to Type structures.
292   std::vector<Type*> types_;
293   // Version of export data we're reading.
294   Export_data_version version_;
295 };
296 
297 // Read import data from a string.
298 
299 class Stream_from_string : public Import::Stream
300 {
301  public:
Stream_from_string(const std::string & str)302   Stream_from_string(const std::string& str)
303     : str_(str), pos_(0)
304   { }
305 
306  protected:
307   bool
do_peek(size_t length,const char ** bytes)308   do_peek(size_t length, const char** bytes)
309   {
310     if (this->pos_ + length > this->str_.length())
311       return false;
312     *bytes = this->str_.data() + this->pos_;
313     return true;
314   }
315 
316   void
do_advance(size_t len)317   do_advance(size_t len)
318   { this->pos_ += len; }
319 
320  private:
321   // The string of data we are reading.
322   std::string str_;
323   // The current position within the string.
324   size_t pos_;
325 };
326 
327 // Read import data from a buffer allocated using malloc.
328 
329 class Stream_from_buffer : public Import::Stream
330 {
331  public:
Stream_from_buffer(char * buf,size_t length)332   Stream_from_buffer(char* buf, size_t length)
333     : buf_(buf), length_(length), pos_(0)
334   { }
335 
~Stream_from_buffer()336   ~Stream_from_buffer()
337   { free(this->buf_); }
338 
339  protected:
340   bool
do_peek(size_t length,const char ** bytes)341   do_peek(size_t length, const char** bytes)
342   {
343     if (this->pos_ + length > this->length_)
344       return false;
345     *bytes = this->buf_ + this->pos_;
346     return true;
347   }
348 
349   void
do_advance(size_t len)350   do_advance(size_t len)
351   { this->pos_ += len; }
352 
353  private:
354   // The data we are reading.
355   char* buf_;
356   // The length of the buffer.
357   size_t length_;
358   // The current position within the buffer.
359   size_t pos_;
360 };
361 
362 // Read import data from an open file descriptor.
363 
364 class Stream_from_file : public Import::Stream
365 {
366  public:
367   Stream_from_file(int fd);
368 
369   ~Stream_from_file();
370 
371  protected:
372   bool
373   do_peek(size_t, const char**);
374 
375   void
376   do_advance(size_t);
377 
378  private:
379   // No copying.
380   Stream_from_file(const Stream_from_file&);
381   Stream_from_file& operator=(const Stream_from_file&);
382 
383   // The file descriptor.
384   int fd_;
385   // Data read from the file.
386   std::string data_;
387 };
388 
389 #endif // !defined(GO_IMPORT_H)
390