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