Mercurial > hg > CbC > CbC_gcc
comparison gcc/go/gofrontend/import.h @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
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 // 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 // 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 | |
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 | |
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: | |
302 Stream_from_string(const std::string& str) | |
303 : str_(str), pos_(0) | |
304 { } | |
305 | |
306 protected: | |
307 bool | |
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 | |
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: | |
332 Stream_from_buffer(char* buf, size_t length) | |
333 : buf_(buf), length_(length), pos_(0) | |
334 { } | |
335 | |
336 ~Stream_from_buffer() | |
337 { free(this->buf_); } | |
338 | |
339 protected: | |
340 bool | |
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 | |
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) |