github.com/kidsbmilk/gofronted_all@v0.0.0-20220701224323-6479d5976c5d/go/import.h (about) 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 Block; 15 class Package; 16 class Type; 17 class Named_object; 18 class Named_type; 19 class Expression; 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 }; 90 91 // This class manages importing Go declarations. 92 93 class Import : public Import_expression 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 104 // Set the position, for error messages. 105 void 106 set_pos(int pos) 107 { this->pos_ = pos; } 108 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 243 // Read LENGTH characters into *OUT and advance past them. On 244 // EOF reports an error and sets *OUT to an empty string. 245 void 246 read(size_t length, std::string* out); 247 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 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 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 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 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 307 // Read a type. 308 Type* 309 read_type(); 310 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 318 // Read an escape note. 319 std::string 320 read_escape(); 321 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 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 369 // Read an indirectimport line. 370 void 371 read_one_indirect_import(); 372 373 // Read the import control functions and init graph. 374 void 375 read_import_init_fns(Gogo*); 376 377 // Read the types. 378 bool 379 read_types(); 380 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. 394 void 395 import_func(Package*); 396 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 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 424 // Finalize methods for newly imported types. 425 void 426 finalize_methods(); 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_; 439 // Mapping from package index to package. 440 std::vector<Package*> packages_; 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_; 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 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 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 776 #endif // !defined(GO_IMPORT_H)