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