OSDN Git Service

compiler: Don't use memcmp for structs/arrays with padding.
[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 #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
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   static Stream*
128   open_package(const std::string& filename, Location location);
129
130   // Constructor.
131   Import(Stream*, Location);
132
133   // Register the builtin types.
134   void
135   register_builtin_types(Gogo*);
136
137   // Import everything defined in the stream.  LOCAL_NAME is the local
138   // name to be used for bindings; if it is the string "." then
139   // bindings should be inserted in the global scope.  If LOCAL_NAME
140   // is the empty string then the name of the package itself is the
141   // local name.  This returns the imported package, or NULL on error.
142   Package*
143   import(Gogo*, const std::string& local_name, bool is_local_name_exported);
144
145   // The location of the import statement.
146   Location
147   location() const
148   { return this->location_; }
149
150   // Return the next character.
151   int
152   peek_char()
153   { return this->stream_->peek_char(); }
154
155   // Return the next character and advance.
156   int
157   get_char()
158   { return this->stream_->get_char(); }
159
160   // Return true at the end of the stream.
161   bool
162   at_eof()
163   { return this->stream_->at_eof(); }
164
165   // Return whether the next bytes match STR.
166   bool
167   match_c_string(const char* str)
168   { return this->stream_->match_c_string(str); }
169
170   // Require that the next bytes match STR.
171   void
172   require_c_string(const char* str)
173   { this->stream_->require_c_string(this->location_, str); }
174
175   // Advance the stream SKIP bytes.
176   void
177   advance(size_t skip)
178   { this->stream_->advance(skip); }
179
180   // Read an identifier.
181   std::string
182   read_identifier();
183
184   // Read a type.
185   Type*
186   read_type();
187
188   // The name used for parameters, receivers, and results in imported
189   // function types.
190   static const char* const import_marker;
191
192  private:
193   static Stream*
194   try_package_in_directory(const std::string&, Location);
195
196   static int
197   try_suffixes(std::string*);
198
199   static Stream*
200   find_export_data(const std::string& filename, int fd, Location);
201
202   static Stream*
203   find_object_export_data(const std::string& filename, int fd,
204                           off_t offset, Location);
205
206   static const int archive_magic_len = 8;
207
208   static bool
209   is_archive_magic(const char*);
210
211   static Stream*
212   find_archive_export_data(const std::string& filename, int fd,
213                            Location);
214
215   // Read the import control functions.
216   void
217   read_import_init_fns(Gogo*);
218
219   // Import a constant.
220   void
221   import_const();
222
223   // Import a type.
224   void
225   import_type();
226
227   // Import a variable.
228   void
229   import_var();
230
231   // Import a function.
232   Named_object*
233   import_func(Package*);
234
235   // Register a single builtin type.
236   void
237   register_builtin_type(Gogo*, const char* name, Builtin_code);
238
239   // Get an integer from a string.
240   bool
241   string_to_int(const std::string&, bool is_neg_ok, int* ret);
242
243   // The general IR.
244   Gogo* gogo_;
245   // The stream from which to read import data.
246   Stream* stream_;
247   // The location of the import statement we are processing.
248   Location location_;
249   // The package we are importing.
250   Package* package_;
251   // Whether to add new objects to the global scope, rather than to a
252   // package scope.
253   bool add_to_globals_;
254   // Mapping from negated builtin type codes to Type structures.
255   std::vector<Named_type*> builtin_types_;
256   // Mapping from exported type codes to Type structures.
257   std::vector<Type*> types_;
258 };
259
260 // Read import data from a string.
261
262 class Stream_from_string : public Import::Stream
263 {
264  public:
265   Stream_from_string(const std::string& str)
266     : str_(str), pos_(0)
267   { }
268
269  protected:
270   bool
271   do_peek(size_t length, const char** bytes)
272   {
273     if (this->pos_ + length > this->str_.length())
274       return false;
275     *bytes = this->str_.data() + this->pos_;
276     return true;
277   }
278
279   void
280   do_advance(size_t len)
281   { this->pos_ += len; }
282
283  private:
284   // The string of data we are reading.
285   std::string str_;
286   // The current position within the string.
287   size_t pos_;
288 };
289
290 // Read import data from a buffer allocated using malloc.
291
292 class Stream_from_buffer : public Import::Stream
293 {
294  public:
295   Stream_from_buffer(char* buf, size_t length)
296     : buf_(buf), length_(length), pos_(0)
297   { }
298
299   ~Stream_from_buffer()
300   { free(this->buf_); }
301
302  protected:
303   bool
304   do_peek(size_t length, const char** bytes)
305   {
306     if (this->pos_ + length > this->length_)
307       return false;
308     *bytes = this->buf_ + this->pos_;
309     return true;
310   }
311
312   void
313   do_advance(size_t len)
314   { this->pos_ += len; }
315
316  private:
317   // The data we are reading.
318   char* buf_;
319   // The length of the buffer.
320   size_t length_;
321   // The current position within the buffer.
322   size_t pos_;
323 };
324
325 // Read import data from an open file descriptor.
326
327 class Stream_from_file : public Import::Stream
328 {
329  public:
330   Stream_from_file(int fd);
331
332   ~Stream_from_file();
333
334  protected:
335   bool
336   do_peek(size_t, const char**);
337
338   void
339   do_advance(size_t);
340
341  private:
342   // No copying.
343   Stream_from_file(const Stream_from_file&);
344   Stream_from_file& operator=(const Stream_from_file&);
345
346   // The file descriptor.
347   int fd_;
348   // Data read from the file.
349   std::string data_;
350 };
351
352 #endif // !defined(GO_IMPORT_H)