111
|
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;
|
145
|
14 class Block;
|
111
|
15 class Package;
|
|
16 class Type;
|
|
17 class Named_object;
|
|
18 class Named_type;
|
|
19 class Expression;
|
145
|
20 class Import_function_body;
|
|
21 class Temporary_statement;
|
|
22 class Unnamed_label;
|
|
23 class Finalize_methods;
|
|
24
|
|
25 // Expressions can be imported either directly from import data (for
|
|
26 // simple constant expressions that can appear in a const declaration
|
|
27 // or as an array length in a type definition) or from an exported
|
|
28 // function body (for an inlinable function). These two cases happen
|
|
29 // at different points in the compilation and have different
|
|
30 // requirements, so it's not easy to unify them. Import_expression is
|
|
31 // an abstract interface that permits the expression import code to
|
|
32 // work at either point. When importing expressions that only occur
|
|
33 // for an inlinable function, the ifb method is available to get the
|
|
34 // full Import_function_body.
|
|
35
|
|
36 class Import_expression
|
|
37 {
|
|
38 public:
|
|
39 // Return the import function body. This should only be called for
|
|
40 // expressions that can not appear outside of an inlinable function
|
|
41 // body.
|
|
42 virtual Import_function_body*
|
|
43 ifb() = 0;
|
|
44
|
|
45 // The location to report in an error message.
|
|
46 virtual Location
|
|
47 location() const = 0;
|
|
48
|
|
49 // Peek at the next character in the input, returning a value from 0
|
|
50 // to 0xff. Returns -1 at end of stream.
|
|
51 virtual int
|
|
52 peek_char() = 0;
|
|
53
|
|
54 // Return the next character and advance.
|
|
55 virtual int
|
|
56 get_char() = 0;
|
|
57
|
|
58 // Return true if the next bytes match STR.
|
|
59 virtual bool
|
|
60 match_c_string(const char* str) = 0;
|
|
61
|
|
62 // Require that the next bytes match STR.
|
|
63 virtual void
|
|
64 require_c_string(const char* str) = 0;
|
|
65
|
|
66 // Advance the stream SKIP bytes.
|
|
67 virtual void
|
|
68 advance(size_t skip) = 0;
|
|
69
|
|
70 // Read an identifier.
|
|
71 virtual std::string
|
|
72 read_identifier() = 0;
|
|
73
|
|
74 // Read a type.
|
|
75 virtual Type*
|
|
76 read_type() = 0;
|
|
77
|
|
78 // Return the maximum valid package index.
|
|
79 virtual size_t
|
|
80 max_package_index() const = 0;
|
|
81
|
|
82 // Return the package for a package index.
|
|
83 virtual Package*
|
|
84 package_at_index(int index) = 0;
|
|
85
|
|
86 // Return the version number of the export data we're reading.
|
|
87 virtual Export_data_version
|
|
88 version() const = 0;
|
|
89 };
|
111
|
90
|
|
91 // This class manages importing Go declarations.
|
|
92
|
145
|
93 class Import : public Import_expression
|
111
|
94 {
|
|
95 public:
|
|
96 // The Stream class is an interface used to read the data. The
|
|
97 // caller should instantiate a child of this class.
|
|
98 class Stream
|
|
99 {
|
|
100 public:
|
|
101 Stream();
|
|
102 virtual ~Stream();
|
|
103
|
131
|
104 // Set the position, for error messages.
|
|
105 void
|
|
106 set_pos(int pos)
|
|
107 { this->pos_ = pos; }
|
|
108
|
111
|
109 // Return whether we have seen an error.
|
|
110 bool
|
|
111 saw_error() const
|
|
112 { return this->saw_error_; }
|
|
113
|
|
114 // Record that we've seen an error.
|
|
115 void
|
|
116 set_saw_error()
|
|
117 { this->saw_error_ = true; }
|
|
118
|
|
119 // Return the next character (a value from 0 to 0xff) without
|
|
120 // advancing. Returns -1 at end of stream.
|
|
121 int
|
|
122 peek_char();
|
|
123
|
|
124 // Look for LENGTH characters, setting *BYTES to point to them.
|
|
125 // Returns false if the bytes are not available. Does not
|
|
126 // advance.
|
|
127 bool
|
|
128 peek(size_t length, const char** bytes)
|
|
129 { return this->do_peek(length, bytes); }
|
|
130
|
|
131 // Return the next character (a value from 0 to 0xff) and advance
|
|
132 // the read position by 1. Returns -1 at end of stream.
|
|
133 int
|
|
134 get_char()
|
|
135 {
|
|
136 int c = this->peek_char();
|
|
137 this->advance(1);
|
|
138 return c;
|
|
139 }
|
|
140
|
|
141 // Return true if at the end of the stream.
|
|
142 bool
|
|
143 at_eof()
|
|
144 { return this->peek_char() == -1; }
|
|
145
|
|
146 // Return true if the next bytes match STR.
|
|
147 bool
|
|
148 match_c_string(const char* str)
|
|
149 { return this->match_bytes(str, strlen(str)); }
|
|
150
|
|
151 // Return true if the next LENGTH bytes match BYTES.
|
|
152 bool
|
|
153 match_bytes(const char* bytes, size_t length);
|
|
154
|
|
155 // Give an error if the next bytes do not match STR. Advance the
|
|
156 // read position by the length of STR.
|
|
157 void
|
|
158 require_c_string(Location location, const char* str)
|
|
159 { this->require_bytes(location, str, strlen(str)); }
|
|
160
|
|
161 // Given an error if the next LENGTH bytes do not match BYTES.
|
|
162 // Advance the read position by LENGTH.
|
|
163 void
|
|
164 require_bytes(Location, const char* bytes, size_t length);
|
|
165
|
|
166 // Advance the read position by SKIP bytes.
|
|
167 void
|
|
168 advance(size_t skip)
|
|
169 {
|
|
170 this->do_advance(skip);
|
|
171 this->pos_ += skip;
|
|
172 }
|
|
173
|
|
174 // Return the current read position. This returns int because it
|
|
175 // is more convenient in error reporting. FIXME.
|
|
176 int
|
|
177 pos()
|
|
178 { return static_cast<int>(this->pos_); }
|
|
179
|
|
180 protected:
|
|
181 // This function should set *BYTES to point to a buffer holding
|
|
182 // the LENGTH bytes at the current read position. It should
|
|
183 // return false if the bytes are not available. This should not
|
|
184 // change the current read position.
|
|
185 virtual bool
|
|
186 do_peek(size_t length, const char** bytes) = 0;
|
|
187
|
|
188 // This function should advance the current read position LENGTH
|
|
189 // bytes.
|
|
190 virtual void
|
|
191 do_advance(size_t skip) = 0;
|
|
192
|
|
193 private:
|
|
194 // The current read position.
|
|
195 size_t pos_;
|
|
196 // True if we've seen an error reading from this stream.
|
|
197 bool saw_error_;
|
|
198 };
|
|
199
|
|
200 // Find import data. This searches the file system for FILENAME and
|
|
201 // returns a pointer to a Stream object to read the data that it
|
|
202 // exports. LOCATION is the location of the import statement.
|
|
203 // RELATIVE_IMPORT_PATH is used as a prefix for a relative import.
|
|
204 static Stream*
|
|
205 open_package(const std::string& filename, Location location,
|
|
206 const std::string& relative_import_path);
|
|
207
|
|
208 // Constructor.
|
|
209 Import(Stream*, Location);
|
|
210
|
|
211 // Register the builtin types.
|
|
212 void
|
|
213 register_builtin_types(Gogo*);
|
|
214
|
|
215 // Import everything defined in the stream. LOCAL_NAME is the local
|
|
216 // name to be used for bindings; if it is the string "." then
|
|
217 // bindings should be inserted in the global scope. If LOCAL_NAME
|
|
218 // is the empty string then the name of the package itself is the
|
|
219 // local name. This returns the imported package, or NULL on error.
|
|
220 Package*
|
|
221 import(Gogo*, const std::string& local_name, bool is_local_name_exported);
|
|
222
|
|
223 // The location of the import statement.
|
|
224 Location
|
|
225 location() const
|
|
226 { return this->location_; }
|
|
227
|
|
228 // Return the package we are importing.
|
|
229 Package*
|
|
230 package() const
|
|
231 { return this->package_; }
|
|
232
|
|
233 // Return the next character.
|
|
234 int
|
|
235 peek_char()
|
|
236 { return this->stream_->peek_char(); }
|
|
237
|
|
238 // Return the next character and advance.
|
|
239 int
|
|
240 get_char()
|
|
241 { return this->stream_->get_char(); }
|
|
242
|
145
|
243 // Read LENGTH characters into a string and advance past them. On
|
|
244 // EOF reports an error and returns an empty string.
|
|
245 std::string
|
|
246 read(size_t length);
|
|
247
|
111
|
248 // Return true at the end of the stream.
|
|
249 bool
|
|
250 at_eof()
|
|
251 { return this->stream_->at_eof(); }
|
|
252
|
|
253 // Return whether the next bytes match STR.
|
|
254 bool
|
|
255 match_c_string(const char* str)
|
|
256 { return this->stream_->match_c_string(str); }
|
|
257
|
|
258 // Require that the next bytes match STR.
|
|
259 void
|
|
260 require_c_string(const char* str)
|
|
261 { this->stream_->require_c_string(this->location_, str); }
|
|
262
|
|
263 // Advance the stream SKIP bytes.
|
|
264 void
|
|
265 advance(size_t skip)
|
|
266 { this->stream_->advance(skip); }
|
|
267
|
145
|
268 // Stream position, for error reporting.
|
|
269 int
|
|
270 pos()
|
|
271 { return this->stream_->pos(); }
|
|
272
|
|
273 // Return the version number of the export data we're reading.
|
|
274 Export_data_version
|
|
275 version() const { return this->version_; }
|
|
276
|
131
|
277 // Skip a semicolon if using an older version.
|
|
278 void
|
|
279 require_semicolon_if_old_version()
|
|
280 {
|
|
281 if (this->version_ == EXPORT_FORMAT_V1
|
|
282 || this->version_ == EXPORT_FORMAT_V2)
|
|
283 this->require_c_string(";");
|
|
284 }
|
|
285
|
111
|
286 // Read an identifier.
|
|
287 std::string
|
|
288 read_identifier();
|
|
289
|
|
290 // Read a name. This is like read_identifier, except that a "?" is
|
|
291 // returned as an empty string. This matches Export::write_name.
|
|
292 std::string
|
|
293 read_name();
|
|
294
|
145
|
295 // Return the maximum valid package index. This is the size of
|
|
296 // packages_ because we will subtract 1 in package_at_index.
|
|
297 size_t
|
|
298 max_package_index() const
|
|
299 { return this->packages_.size(); }
|
|
300
|
|
301 // Return the package at an index. (We subtract 1 because package
|
|
302 // index 0 is not used.)
|
|
303 Package*
|
|
304 package_at_index(int index)
|
|
305 { return this->packages_.at(index - 1); }
|
|
306
|
111
|
307 // Read a type.
|
|
308 Type*
|
|
309 read_type();
|
|
310
|
145
|
311 // Return the type for a type index. INPUT_NAME and INPUT_OFFSET
|
|
312 // are only for error reporting. PARSED is set to whether we parsed
|
|
313 // the type information for a new type.
|
|
314 Type*
|
|
315 type_for_index(int index, const std::string& input_name,
|
|
316 size_t input_offset, bool* parsed);
|
|
317
|
111
|
318 // Read an escape note.
|
|
319 std::string
|
|
320 read_escape();
|
|
321
|
145
|
322 // Clear the stream when it is no longer accessible.
|
|
323 void
|
|
324 clear_stream()
|
|
325 { this->stream_ = NULL; }
|
|
326
|
|
327 // Just so that Import implements Import_expression.
|
|
328 Import_function_body*
|
|
329 ifb()
|
|
330 { return NULL; }
|
|
331
|
|
332 // Read a qualified identifier from an Import_expression. Sets
|
|
333 // *NAME, *PKG, and *IS_EXPORTED, and reports whether it succeeded.
|
|
334 static bool
|
|
335 read_qualified_identifier(Import_expression*, std::string* name,
|
|
336 Package** pkg, bool* is_exported);
|
|
337
|
111
|
338 private:
|
|
339 static Stream*
|
|
340 try_package_in_directory(const std::string&, Location);
|
|
341
|
|
342 static int
|
|
343 try_suffixes(std::string*);
|
|
344
|
|
345 static Stream*
|
|
346 find_export_data(const std::string& filename, int fd, Location);
|
|
347
|
|
348 static Stream*
|
|
349 find_object_export_data(const std::string& filename, int fd,
|
|
350 off_t offset, Location);
|
|
351
|
|
352 static const int archive_magic_len = 8;
|
|
353
|
|
354 static bool
|
|
355 is_archive_magic(const char*);
|
|
356
|
|
357 static Stream*
|
|
358 find_archive_export_data(const std::string& filename, int fd,
|
|
359 Location);
|
|
360
|
|
361 // Read a package line.
|
|
362 void
|
|
363 read_one_package();
|
|
364
|
|
365 // Read an import line.
|
|
366 void
|
|
367 read_one_import();
|
|
368
|
131
|
369 // Read an indirectimport line.
|
|
370 void
|
|
371 read_one_indirect_import();
|
|
372
|
111
|
373 // Read the import control functions and init graph.
|
|
374 void
|
|
375 read_import_init_fns(Gogo*);
|
|
376
|
131
|
377 // Read the types.
|
|
378 bool
|
|
379 read_types();
|
|
380
|
111
|
381 // Import a constant.
|
|
382 void
|
|
383 import_const();
|
|
384
|
|
385 // Import a type.
|
|
386 void
|
|
387 import_type();
|
|
388
|
|
389 // Import a variable.
|
|
390 void
|
|
391 import_var();
|
|
392
|
|
393 // Import a function.
|
145
|
394 void
|
111
|
395 import_func(Package*);
|
|
396
|
131
|
397 // Parse a type definition.
|
|
398 bool
|
|
399 parse_type(int index);
|
|
400
|
|
401 // Read a named type and store it at this->type_[index].
|
|
402 Type*
|
|
403 read_named_type(int index);
|
|
404
|
111
|
405 // Register a single builtin type.
|
|
406 void
|
|
407 register_builtin_type(Gogo*, const char* name, Builtin_code);
|
|
408
|
|
409 // Get an integer from a string.
|
|
410 bool
|
|
411 string_to_int(const std::string&, bool is_neg_ok, int* ret);
|
|
412
|
|
413 // Get an unsigned integer from a string.
|
|
414 bool
|
|
415 string_to_unsigned(const std::string& s, unsigned* ret)
|
|
416 {
|
|
417 int ivalue;
|
|
418 if (!this->string_to_int(s, false, &ivalue))
|
|
419 return false;
|
|
420 *ret = static_cast<unsigned>(ivalue);
|
|
421 return true;
|
|
422 }
|
|
423
|
145
|
424 // Finalize methods for newly imported types.
|
|
425 void
|
|
426 finalize_methods();
|
111
|
427
|
|
428 // The general IR.
|
|
429 Gogo* gogo_;
|
|
430 // The stream from which to read import data.
|
|
431 Stream* stream_;
|
|
432 // The location of the import statement we are processing.
|
|
433 Location location_;
|
|
434 // The package we are importing.
|
|
435 Package* package_;
|
|
436 // Whether to add new objects to the global scope, rather than to a
|
|
437 // package scope.
|
|
438 bool add_to_globals_;
|
145
|
439 // Mapping from package index to package.
|
|
440 std::vector<Package*> packages_;
|
131
|
441 // All type data.
|
|
442 std::string type_data_;
|
|
443 // Position of type data in the stream.
|
|
444 int type_pos_;
|
|
445 // Mapping from type code to offset/length in type_data_.
|
|
446 std::vector<std::pair<size_t, size_t> > type_offsets_;
|
111
|
447 // Mapping from negated builtin type codes to Type structures.
|
|
448 std::vector<Named_type*> builtin_types_;
|
|
449 // Mapping from exported type codes to Type structures.
|
|
450 std::vector<Type*> types_;
|
|
451 // Version of export data we're reading.
|
|
452 Export_data_version version_;
|
|
453 };
|
|
454
|
|
455 // Read import data from a string.
|
|
456
|
|
457 class Stream_from_string : public Import::Stream
|
|
458 {
|
|
459 public:
|
|
460 Stream_from_string(const std::string& str)
|
|
461 : str_(str), pos_(0)
|
|
462 { }
|
|
463
|
|
464 protected:
|
|
465 bool
|
|
466 do_peek(size_t length, const char** bytes)
|
|
467 {
|
|
468 if (this->pos_ + length > this->str_.length())
|
|
469 return false;
|
|
470 *bytes = this->str_.data() + this->pos_;
|
|
471 return true;
|
|
472 }
|
|
473
|
|
474 void
|
|
475 do_advance(size_t len)
|
|
476 { this->pos_ += len; }
|
|
477
|
|
478 private:
|
|
479 // The string of data we are reading.
|
|
480 std::string str_;
|
|
481 // The current position within the string.
|
|
482 size_t pos_;
|
|
483 };
|
|
484
|
|
485 // Read import data from a buffer allocated using malloc.
|
|
486
|
|
487 class Stream_from_buffer : public Import::Stream
|
|
488 {
|
|
489 public:
|
|
490 Stream_from_buffer(char* buf, size_t length)
|
|
491 : buf_(buf), length_(length), pos_(0)
|
|
492 { }
|
|
493
|
|
494 ~Stream_from_buffer()
|
|
495 { free(this->buf_); }
|
|
496
|
|
497 protected:
|
|
498 bool
|
|
499 do_peek(size_t length, const char** bytes)
|
|
500 {
|
|
501 if (this->pos_ + length > this->length_)
|
|
502 return false;
|
|
503 *bytes = this->buf_ + this->pos_;
|
|
504 return true;
|
|
505 }
|
|
506
|
|
507 void
|
|
508 do_advance(size_t len)
|
|
509 { this->pos_ += len; }
|
|
510
|
|
511 private:
|
|
512 // The data we are reading.
|
|
513 char* buf_;
|
|
514 // The length of the buffer.
|
|
515 size_t length_;
|
|
516 // The current position within the buffer.
|
|
517 size_t pos_;
|
|
518 };
|
|
519
|
|
520 // Read import data from an open file descriptor.
|
|
521
|
|
522 class Stream_from_file : public Import::Stream
|
|
523 {
|
|
524 public:
|
|
525 Stream_from_file(int fd);
|
|
526
|
|
527 ~Stream_from_file();
|
|
528
|
|
529 protected:
|
|
530 bool
|
|
531 do_peek(size_t, const char**);
|
|
532
|
|
533 void
|
|
534 do_advance(size_t);
|
|
535
|
|
536 private:
|
|
537 // No copying.
|
|
538 Stream_from_file(const Stream_from_file&);
|
|
539 Stream_from_file& operator=(const Stream_from_file&);
|
|
540
|
|
541 // The file descriptor.
|
|
542 int fd_;
|
|
543 // Data read from the file.
|
|
544 std::string data_;
|
|
545 };
|
|
546
|
131
|
547 // Read import data from an offset into a std::string. This uses a
|
|
548 // reference to the string, to avoid copying, so the string must be
|
|
549 // kept alive through some other mechanism.
|
|
550
|
|
551 class Stream_from_string_ref : public Import::Stream
|
|
552 {
|
|
553 public:
|
|
554 Stream_from_string_ref(const std::string& str, size_t offset, size_t length)
|
|
555 : str_(str), pos_(offset), end_(offset + length)
|
|
556 { }
|
|
557
|
|
558 ~Stream_from_string_ref()
|
|
559 {}
|
|
560
|
|
561 protected:
|
|
562 bool
|
|
563 do_peek(size_t length, const char** bytes)
|
|
564 {
|
|
565 if (this->pos_ + length > this->end_)
|
|
566 return false;
|
|
567 *bytes = &this->str_[this->pos_];
|
|
568 return true;
|
|
569 }
|
|
570
|
|
571 void
|
|
572 do_advance(size_t length)
|
|
573 { this->pos_ += length; }
|
|
574
|
|
575 private:
|
|
576 // A reference to the string we are reading from.
|
|
577 const std::string& str_;
|
|
578 // The current offset into the string.
|
|
579 size_t pos_;
|
|
580 // The index after the last byte we can read.
|
|
581 size_t end_;
|
|
582 };
|
|
583
|
145
|
584 // Class to manage importing a function body. This is passed around
|
|
585 // to Statements and Expressions. It parses the function into the IR.
|
|
586
|
|
587 class Import_function_body : public Import_expression
|
|
588 {
|
|
589 public:
|
|
590 Import_function_body(Gogo* gogo, Import* imp, Named_object* named_object,
|
|
591 const std::string& body, size_t off, Block* block,
|
|
592 int indent);
|
|
593 ~Import_function_body();
|
|
594
|
|
595 // The IR.
|
|
596 Gogo*
|
|
597 gogo()
|
|
598 { return this->gogo_; }
|
|
599
|
|
600 // The location to report in an error message.
|
|
601 Location
|
|
602 location() const
|
|
603 { return this->imp_->location(); }
|
|
604
|
|
605 // The function we are importing.
|
|
606 Named_object*
|
|
607 function() const
|
|
608 { return this->named_object_; }
|
|
609
|
|
610 // A reference to the body we are reading.
|
|
611 const std::string&
|
|
612 body() const
|
|
613 { return this->body_; }
|
|
614
|
|
615 // The current offset into the body.
|
|
616 size_t
|
|
617 off()
|
|
618 { return this->off_; }
|
|
619
|
|
620 // Update the offset into the body.
|
|
621 void
|
|
622 set_off(size_t off)
|
|
623 { this->off_ = off; }
|
|
624
|
|
625 // Advance the offset by SKIP bytes.
|
|
626 void
|
|
627 advance(size_t skip)
|
|
628 { this->off_ += skip; }
|
|
629
|
|
630 // The current block.
|
|
631 Block*
|
|
632 block()
|
|
633 { return this->blocks_.back(); }
|
|
634
|
|
635 // Begin importing a new block BLOCK nested within the current block.
|
|
636 void
|
|
637 begin_block(Block *block)
|
|
638 { this->blocks_.push_back(block); }
|
|
639
|
|
640 // Record the fact that we're done importing the current block.
|
|
641 void
|
|
642 finish_block()
|
|
643 { this->blocks_.pop_back(); }
|
|
644
|
|
645 // The current indentation.
|
|
646 int
|
|
647 indent() const
|
|
648 { return this->indent_; }
|
|
649
|
|
650 // Increment the indentation level.
|
|
651 void
|
|
652 increment_indent()
|
|
653 { ++this->indent_; }
|
|
654
|
|
655 // Decrement the indentation level.
|
|
656 void
|
|
657 decrement_indent()
|
|
658 { --this->indent_; }
|
|
659
|
|
660 // The name of the function we are parsing.
|
|
661 const std::string&
|
|
662 name() const;
|
|
663
|
|
664 // Return the next character in the input stream, or -1 at the end.
|
|
665 int
|
|
666 peek_char()
|
|
667 {
|
|
668 if (this->body_.length() <= this->off_)
|
|
669 return -1;
|
|
670 return static_cast<unsigned char>(this->body_[this->off_]);
|
|
671 }
|
|
672
|
|
673 // Return the next character and advance.
|
|
674 int
|
|
675 get_char()
|
|
676 {
|
|
677 if (this->body_.length() <= this->off_)
|
|
678 return -1;
|
|
679 int c = static_cast<unsigned char>(this->body_[this->off_]);
|
|
680 this->off_++;
|
|
681 return c;
|
|
682 }
|
|
683
|
|
684 // Return whether the C string matches the current body position.
|
|
685 bool
|
|
686 match_c_string(const char* str)
|
|
687 {
|
|
688 size_t len = strlen(str);
|
|
689 return (this->body_.length() >= this->off_ + len
|
|
690 && this->body_.compare(this->off_, len, str) == 0);
|
|
691 }
|
|
692
|
|
693 // Give an error if the next bytes do not match STR. Advance the
|
|
694 // offset by the length of STR.
|
|
695 void
|
|
696 require_c_string(const char* str);
|
|
697
|
|
698 // Read an identifier.
|
|
699 std::string
|
|
700 read_identifier();
|
|
701
|
|
702 // Read a type.
|
|
703 Type*
|
|
704 read_type();
|
|
705
|
|
706 Export_data_version
|
|
707 version() const
|
|
708 { return this->imp_->version(); }
|
|
709
|
|
710 // Record the index of a temporary statement.
|
|
711 void
|
|
712 record_temporary(Temporary_statement*, unsigned int);
|
|
713
|
|
714 // Return a temporary statement given an index.
|
|
715 Temporary_statement*
|
|
716 temporary_statement(unsigned int);
|
|
717
|
|
718 // Return an unnamed label given an index, defining the label if we
|
|
719 // haven't seen it already.
|
|
720 Unnamed_label*
|
|
721 unnamed_label(unsigned int, Location);
|
|
722
|
|
723 // Implement Import_expression.
|
|
724 Import_function_body*
|
|
725 ifb()
|
|
726 { return this; }
|
|
727
|
|
728 // Return the maximum valid package index.
|
|
729 size_t
|
|
730 max_package_index() const
|
|
731 { return this->imp_->max_package_index(); }
|
|
732
|
|
733 // Return the package at an index.
|
|
734 Package*
|
|
735 package_at_index(int index)
|
|
736 { return this->imp_->package_at_index(index); }
|
|
737
|
|
738 // Return whether we have seen an error.
|
|
739 bool
|
|
740 saw_error() const
|
|
741 { return this->saw_error_; }
|
|
742
|
|
743 // Record that we have seen an error.
|
|
744 void
|
|
745 set_saw_error()
|
|
746 { this->saw_error_ = true; }
|
|
747
|
|
748 private:
|
|
749 static size_t
|
|
750 next_size(size_t);
|
|
751
|
|
752 // The IR.
|
|
753 Gogo* gogo_;
|
|
754 // The importer.
|
|
755 Import* imp_;
|
|
756 // The function we are parsing.
|
|
757 Named_object* named_object_;
|
|
758 // The exported data we are parsing. Note that this is a reference;
|
|
759 // the body string must laster longer than this object.
|
|
760 const std::string& body_;
|
|
761 // The current offset into body_.
|
|
762 size_t off_;
|
|
763 // Stack to record nesting of blocks being imported.
|
|
764 std::vector<Block *> blocks_;
|
|
765 // Current expected indentation level.
|
|
766 int indent_;
|
|
767 // Temporary statements by index.
|
|
768 std::vector<Temporary_statement*> temporaries_;
|
|
769 // Unnamed labels by index.
|
|
770 std::vector<Unnamed_label*> labels_;
|
|
771 // Whether we've seen an error. Used to avoid reporting excess
|
|
772 // errors.
|
|
773 bool saw_error_;
|
|
774 };
|
|
775
|
111
|
776 #endif // !defined(GO_IMPORT_H)
|