OSDN Git Service

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