github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/go/import.cc (about) 1 // import.cc -- Go frontend import declarations. 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 #include "go-system.h" 8 9 #include "filenames.h" 10 11 #include "go-c.h" 12 #include "go-diagnostics.h" 13 #include "gogo.h" 14 #include "lex.h" 15 #include "types.h" 16 #include "export.h" 17 #include "import.h" 18 19 #ifndef O_BINARY 20 #define O_BINARY 0 21 #endif 22 23 // The list of paths we search for import files. 24 25 static std::vector<std::string> search_path; 26 27 // Add a directory to the search path. This is called from the option 28 // handling language hook. 29 30 GO_EXTERN_C 31 void 32 go_add_search_path(const char* path) 33 { 34 search_path.push_back(std::string(path)); 35 } 36 37 // Find import data. This searches the file system for FILENAME and 38 // returns a pointer to a Stream object to read the data that it 39 // exports. If the file is not found, it returns NULL. 40 41 // When FILENAME is not an absolute path and does not start with ./ or 42 // ../, we use the search path provided by -I and -L options. 43 44 // When FILENAME does start with ./ or ../, we use 45 // RELATIVE_IMPORT_PATH as a prefix. 46 47 // When FILENAME does not exist, we try modifying FILENAME to find the 48 // file. We use the first of these which exists: 49 // * We append ".gox". 50 // * We turn the base of FILENAME into libFILENAME.so. 51 // * We turn the base of FILENAME into libFILENAME.a. 52 // * We append ".o". 53 54 // When using a search path, we apply each of these transformations at 55 // each entry on the search path before moving on to the next entry. 56 // If the file exists, but does not contain any Go export data, we 57 // stop; we do not keep looking for another file with the same name 58 // later in the search path. 59 60 Import::Stream* 61 Import::open_package(const std::string& filename, Location location, 62 const std::string& relative_import_path) 63 { 64 bool is_local; 65 if (IS_ABSOLUTE_PATH(filename)) 66 is_local = true; 67 else if (filename[0] == '.' 68 && (filename[1] == '\0' || IS_DIR_SEPARATOR(filename[1]))) 69 is_local = true; 70 else if (filename[0] == '.' 71 && filename[1] == '.' 72 && (filename[2] == '\0' || IS_DIR_SEPARATOR(filename[2]))) 73 is_local = true; 74 else 75 is_local = false; 76 77 std::string fn = filename; 78 if (is_local && !IS_ABSOLUTE_PATH(filename) && !relative_import_path.empty()) 79 { 80 if (fn == ".") 81 { 82 // A special case. 83 fn = relative_import_path; 84 } 85 else if (fn[0] == '.' && fn[1] == '.' 86 && (fn[2] == '\0' || IS_DIR_SEPARATOR(fn[2]))) 87 { 88 // We are going to join relative_import_path and fn, and it 89 // will look like DIR/../PATH. But DIR does not necessarily 90 // exist in this case, and if it doesn't the use of .. will 91 // fail although it shouldn't. The gc compiler uses 92 // path.Join here, which cleans up the .., so we need to do 93 // the same. 94 size_t index; 95 for (index = relative_import_path.length() - 1; 96 index > 0 && !IS_DIR_SEPARATOR(relative_import_path[index]); 97 index--) 98 ; 99 if (index > 0) 100 fn = relative_import_path.substr(0, index) + fn.substr(2); 101 else 102 fn = relative_import_path + '/' + fn; 103 } 104 else 105 fn = relative_import_path + '/' + fn; 106 is_local = false; 107 } 108 109 if (!is_local) 110 { 111 for (std::vector<std::string>::const_iterator p = search_path.begin(); 112 p != search_path.end(); 113 ++p) 114 { 115 std::string indir = *p; 116 if (!indir.empty() && indir[indir.size() - 1] != '/') 117 indir += '/'; 118 indir += fn; 119 Stream* s = Import::try_package_in_directory(indir, location); 120 if (s != NULL) 121 return s; 122 } 123 } 124 125 Stream* s = Import::try_package_in_directory(fn, location); 126 if (s != NULL) 127 return s; 128 129 return NULL; 130 } 131 132 // Try to find the export data for FILENAME. 133 134 Import::Stream* 135 Import::try_package_in_directory(const std::string& filename, 136 Location location) 137 { 138 std::string found_filename = filename; 139 int fd = open(found_filename.c_str(), O_RDONLY | O_BINARY); 140 141 if (fd >= 0) 142 { 143 struct stat s; 144 if (fstat(fd, &s) >= 0 && S_ISDIR(s.st_mode)) 145 { 146 close(fd); 147 fd = -1; 148 errno = EISDIR; 149 } 150 } 151 152 if (fd < 0) 153 { 154 if (errno != ENOENT && errno != EISDIR) 155 go_warning_at(location, 0, "%s: %m", filename.c_str()); 156 157 fd = Import::try_suffixes(&found_filename); 158 if (fd < 0) 159 return NULL; 160 } 161 162 // The export data may not be in this file. 163 Stream* s = Import::find_export_data(found_filename, fd, location); 164 if (s != NULL) 165 return s; 166 167 close(fd); 168 169 go_error_at(location, "%s exists but does not contain any Go export data", 170 found_filename.c_str()); 171 172 return NULL; 173 } 174 175 // Given import "*PFILENAME", where *PFILENAME does not exist, try 176 // various suffixes. If we find one, set *PFILENAME to the one we 177 // found. Return the open file descriptor. 178 179 int 180 Import::try_suffixes(std::string* pfilename) 181 { 182 std::string filename = *pfilename + ".gox"; 183 int fd = open(filename.c_str(), O_RDONLY | O_BINARY); 184 if (fd >= 0) 185 { 186 *pfilename = filename; 187 return fd; 188 } 189 190 const char* basename = lbasename(pfilename->c_str()); 191 size_t basename_pos = basename - pfilename->c_str(); 192 filename = pfilename->substr(0, basename_pos) + "lib" + basename + ".so"; 193 fd = open(filename.c_str(), O_RDONLY | O_BINARY); 194 if (fd >= 0) 195 { 196 *pfilename = filename; 197 return fd; 198 } 199 200 filename = pfilename->substr(0, basename_pos) + "lib" + basename + ".a"; 201 fd = open(filename.c_str(), O_RDONLY | O_BINARY); 202 if (fd >= 0) 203 { 204 *pfilename = filename; 205 return fd; 206 } 207 208 filename = *pfilename + ".o"; 209 fd = open(filename.c_str(), O_RDONLY | O_BINARY); 210 if (fd >= 0) 211 { 212 *pfilename = filename; 213 return fd; 214 } 215 216 return -1; 217 } 218 219 // Look for export data in the file descriptor FD. 220 221 Import::Stream* 222 Import::find_export_data(const std::string& filename, int fd, Location location) 223 { 224 // See if we can read this as an object file. 225 Import::Stream* stream = Import::find_object_export_data(filename, fd, 0, 226 location); 227 if (stream != NULL) 228 return stream; 229 230 const int len = MAX(Export::magic_len, Import::archive_magic_len); 231 232 if (lseek(fd, 0, SEEK_SET) < 0) 233 { 234 go_error_at(location, "lseek %s failed: %m", filename.c_str()); 235 return NULL; 236 } 237 238 char buf[len]; 239 ssize_t c = ::read(fd, buf, len); 240 if (c < len) 241 return NULL; 242 243 // Check for a file containing nothing but Go export data. 244 if (memcmp(buf, Export::cur_magic, Export::magic_len) == 0 245 || memcmp(buf, Export::v1_magic, Export::magic_len) == 0 246 || memcmp(buf, Export::v2_magic, Export::magic_len) == 0) 247 return new Stream_from_file(fd); 248 249 // See if we can read this as an archive. 250 if (Import::is_archive_magic(buf)) 251 return Import::find_archive_export_data(filename, fd, location); 252 253 return NULL; 254 } 255 256 // Look for export data in an object file. 257 258 Import::Stream* 259 Import::find_object_export_data(const std::string& filename, 260 int fd, 261 off_t offset, 262 Location location) 263 { 264 char *buf; 265 size_t len; 266 int err; 267 const char *errmsg = go_read_export_data(fd, offset, &buf, &len, &err); 268 if (errmsg != NULL) 269 { 270 if (err == 0) 271 go_error_at(location, "%s: %s", filename.c_str(), errmsg); 272 else 273 go_error_at(location, "%s: %s: %s", filename.c_str(), errmsg, 274 xstrerror(err)); 275 return NULL; 276 } 277 278 if (buf == NULL) 279 return NULL; 280 281 return new Stream_from_buffer(buf, len); 282 } 283 284 // Class Import. 285 286 // Construct an Import object. We make the builtin_types_ vector 287 // large enough to hold all the builtin types. 288 289 Import::Import(Stream* stream, Location location) 290 : gogo_(NULL), stream_(stream), location_(location), package_(NULL), 291 add_to_globals_(false), packages_(), type_data_(), type_pos_(0), 292 type_offsets_(), builtin_types_((- SMALLEST_BUILTIN_CODE) + 1), 293 types_(), version_(EXPORT_FORMAT_UNKNOWN) 294 { 295 } 296 297 // Import the data in the associated stream. 298 299 Package* 300 Import::import(Gogo* gogo, const std::string& local_name, 301 bool is_local_name_exported) 302 { 303 // Hold on to the Gogo structure. Otherwise we need to pass it 304 // through all the import functions, because we need it when reading 305 // a type. 306 this->gogo_ = gogo; 307 308 // A stream of export data can include data from more than one input 309 // file. Here we loop over each input file. 310 Stream* stream = this->stream_; 311 while (!stream->at_eof() && !stream->saw_error()) 312 { 313 // The vector of types is package specific. 314 this->types_.clear(); 315 316 // Check magic string / version number. 317 if (stream->match_bytes(Export::cur_magic, Export::magic_len)) 318 { 319 stream->require_bytes(this->location_, Export::cur_magic, 320 Export::magic_len); 321 this->version_ = EXPORT_FORMAT_CURRENT; 322 } 323 else if (stream->match_bytes(Export::v1_magic, Export::magic_len)) 324 { 325 stream->require_bytes(this->location_, Export::v1_magic, 326 Export::magic_len); 327 this->version_ = EXPORT_FORMAT_V1; 328 } 329 else if (stream->match_bytes(Export::v2_magic, Export::magic_len)) 330 { 331 stream->require_bytes(this->location_, Export::v2_magic, 332 Export::magic_len); 333 this->version_ = EXPORT_FORMAT_V2; 334 } 335 else 336 { 337 go_error_at(this->location_, 338 ("error in import data at %d: invalid magic string"), 339 stream->pos()); 340 return NULL; 341 } 342 343 this->require_c_string("package "); 344 std::string package_name = this->read_identifier(); 345 this->require_semicolon_if_old_version(); 346 this->require_c_string("\n"); 347 348 std::string pkgpath; 349 std::string pkgpath_symbol; 350 if (this->match_c_string("prefix ")) 351 { 352 this->advance(7); 353 std::string unique_prefix = this->read_identifier(); 354 this->require_semicolon_if_old_version(); 355 this->require_c_string("\n"); 356 pkgpath = unique_prefix + '.' + package_name; 357 pkgpath_symbol = (Gogo::pkgpath_for_symbol(unique_prefix) + '.' 358 + Gogo::pkgpath_for_symbol(package_name)); 359 } 360 else 361 { 362 this->require_c_string("pkgpath "); 363 pkgpath = this->read_identifier(); 364 this->require_semicolon_if_old_version(); 365 this->require_c_string("\n"); 366 pkgpath_symbol = Gogo::pkgpath_for_symbol(pkgpath); 367 } 368 369 if (stream->saw_error()) 370 return NULL; 371 372 this->package_ = gogo->add_imported_package(package_name, local_name, 373 is_local_name_exported, 374 pkgpath, pkgpath_symbol, 375 this->location_, 376 &this->add_to_globals_); 377 if (this->package_ == NULL) 378 { 379 stream->set_saw_error(); 380 return NULL; 381 } 382 383 // Read and discard priority if older V1 export data format. 384 if (version() == EXPORT_FORMAT_V1) 385 { 386 this->require_c_string("priority "); 387 std::string priority_string = this->read_identifier(); 388 int prio; 389 if (!this->string_to_int(priority_string, false, &prio)) 390 return NULL; 391 this->require_c_string(";\n"); 392 } 393 394 while (stream->match_c_string("package")) 395 this->read_one_package(); 396 397 while (stream->match_c_string("import")) 398 this->read_one_import(); 399 400 while (stream->match_c_string("indirectimport")) 401 this->read_one_indirect_import(); 402 403 if (stream->match_c_string("init")) 404 this->read_import_init_fns(gogo); 405 406 if (stream->match_c_string("types ")) 407 { 408 if (!this->read_types()) 409 return NULL; 410 } 411 412 // Loop over all the input data for this package. 413 while (!stream->saw_error()) 414 { 415 if (stream->match_c_string("const ")) 416 this->import_const(); 417 else if (stream->match_c_string("type ")) 418 this->import_type(); 419 else if (stream->match_c_string("var ")) 420 this->import_var(); 421 else if (stream->match_c_string("func ")) 422 this->import_func(this->package_); 423 else if (stream->match_c_string("checksum ")) 424 break; 425 else 426 { 427 go_error_at(this->location_, 428 ("error in import data at %d: " 429 "expected %<const%>, %<type%>, %<var%>, " 430 "%<func%>, or %<checksum%>"), 431 stream->pos()); 432 stream->set_saw_error(); 433 return NULL; 434 } 435 } 436 437 // We currently ignore the checksum. In the future we could 438 // store the checksum somewhere in the generated object and then 439 // verify that the checksum matches at link time or at dynamic 440 // load time. 441 this->require_c_string("checksum "); 442 stream->advance(Export::checksum_len * 2); 443 this->require_semicolon_if_old_version(); 444 this->require_c_string("\n"); 445 } 446 447 // Finalize methods for any imported types. This call is made late in the 448 // import process so as to A) avoid finalization of a type whose methods 449 // refer to types that are only partially read in, and B) capture both the 450 // types imported by read_types() directly, and those imported indirectly 451 // because they are referenced by an imported function or variable. 452 // See issues #33013 and #33219 for more on why this is needed. 453 this->finalize_methods(); 454 455 return this->package_; 456 } 457 458 // Read a package line. This let us reliably determine the pkgpath 459 // symbol, even if the package was compiled with a -fgo-prefix option. 460 461 void 462 Import::read_one_package() 463 { 464 this->require_c_string("package "); 465 std::string package_name = this->read_identifier(); 466 this->require_c_string(" "); 467 std::string pkgpath = this->read_identifier(); 468 this->require_c_string(" "); 469 std::string pkgpath_symbol = this->read_identifier(); 470 this->require_semicolon_if_old_version(); 471 this->require_c_string("\n"); 472 473 Package* p = this->gogo_->register_package(pkgpath, pkgpath_symbol, 474 Linemap::unknown_location()); 475 p->set_package_name(package_name, this->location()); 476 } 477 478 // Read an import line. 479 480 void 481 Import::read_one_import() 482 { 483 this->require_c_string("import "); 484 std::string package_name = this->read_identifier(); 485 this->require_c_string(" "); 486 std::string pkgpath = this->read_identifier(); 487 this->require_c_string(" \""); 488 Stream* stream = this->stream_; 489 while (stream->peek_char() != '"') 490 stream->advance(1); 491 this->require_c_string("\""); 492 this->require_semicolon_if_old_version(); 493 this->require_c_string("\n"); 494 495 Package* p = this->gogo_->register_package(pkgpath, "", 496 Linemap::unknown_location()); 497 p->set_package_name(package_name, this->location()); 498 499 this->packages_.push_back(p); 500 } 501 502 // Read an indirectimport line. 503 504 void 505 Import::read_one_indirect_import() 506 { 507 this->require_c_string("indirectimport "); 508 std::string package_name = this->read_identifier(); 509 this->require_c_string(" "); 510 std::string pkgpath = this->read_identifier(); 511 this->require_c_string("\n"); 512 513 Package* p = this->gogo_->register_package(pkgpath, "", 514 Linemap::unknown_location()); 515 p->set_package_name(package_name, this->location()); 516 517 this->packages_.push_back(p); 518 } 519 520 // Read the list of import control functions and/or init graph. 521 522 void 523 Import::read_import_init_fns(Gogo* gogo) 524 { 525 this->require_c_string("init"); 526 527 // Maps init function to index in the "init" clause; needed 528 // to read the init_graph section. 529 std::map<std::string, unsigned> init_idx; 530 531 while (!this->match_c_string("\n") && !this->match_c_string(";")) 532 { 533 int priority = -1; 534 535 this->require_c_string(" "); 536 std::string package_name = this->read_identifier(); 537 this->require_c_string(" "); 538 std::string init_name = this->read_identifier(); 539 if (this->version_ == EXPORT_FORMAT_V1) 540 { 541 // Older version 1 init fcn export data format is: 542 // 543 // <packname> <fcn> <priority> 544 this->require_c_string(" "); 545 std::string prio_string = this->read_identifier(); 546 if (!this->string_to_int(prio_string, false, &priority)) 547 return; 548 } 549 gogo->add_import_init_fn(package_name, init_name, priority); 550 551 // Record the index of this init fcn so that we can look it 552 // up by index in the subsequent init_graph section. 553 unsigned idx = init_idx.size(); 554 init_idx[init_name] = idx; 555 } 556 this->require_semicolon_if_old_version(); 557 this->require_c_string("\n"); 558 559 if (this->match_c_string("init_graph")) 560 { 561 this->require_c_string("init_graph"); 562 563 // Build a vector mapping init fcn slot to Import_init pointer. 564 go_assert(init_idx.size() > 0); 565 std::vector<Import_init*> import_initvec; 566 import_initvec.resize(init_idx.size()); 567 for (std::map<std::string, unsigned>::const_iterator it = 568 init_idx.begin(); 569 it != init_idx.end(); ++it) 570 { 571 const std::string& init_name = it->first; 572 Import_init* ii = gogo->lookup_init(init_name); 573 import_initvec[it->second] = ii; 574 } 575 576 // Init graph format is: 577 // 578 // init_graph <src1> <sink1> <src2> <sink2> ... ; 579 // 580 // where src + sink are init functions indices. 581 582 while (!this->match_c_string("\n") && !this->match_c_string(";")) 583 { 584 this->require_c_string(" "); 585 std::string src_string = this->read_identifier(); 586 unsigned src; 587 if (!this->string_to_unsigned(src_string, &src)) return; 588 589 this->require_c_string(" "); 590 std::string sink_string = this->read_identifier(); 591 unsigned sink; 592 if (!this->string_to_unsigned(sink_string, &sink)) return; 593 594 go_assert(src < import_initvec.size()); 595 Import_init* ii_src = import_initvec[src]; 596 go_assert(sink < import_initvec.size()); 597 Import_init* ii_sink = import_initvec[sink]; 598 599 ii_src->record_precursor_fcn(ii_sink->init_name()); 600 } 601 this->require_semicolon_if_old_version(); 602 this->require_c_string("\n"); 603 } 604 } 605 606 // Import the types. Starting in export format version 3 all the 607 // types are listed first. 608 609 bool 610 Import::read_types() 611 { 612 this->require_c_string("types "); 613 std::string str = this->read_identifier(); 614 int maxp1; 615 if (!this->string_to_int(str, false, &maxp1)) 616 return false; 617 618 this->require_c_string(" "); 619 str = this->read_identifier(); 620 int exportedp1; 621 if (!this->string_to_int(str, false, &exportedp1)) 622 return false; 623 624 this->type_offsets_.resize(maxp1, std::make_pair<size_t, size_t>(0, 0)); 625 size_t total_type_size = 0; 626 // Start at 1 because type index 0 not used. 627 for (int i = 1; i < maxp1; i++) 628 { 629 this->require_c_string(" "); 630 str = this->read_identifier(); 631 int v; 632 if (!this->string_to_int(str, false, &v)) 633 return false; 634 size_t vs = static_cast<size_t>(v); 635 this->type_offsets_[i] = std::make_pair(total_type_size, vs); 636 total_type_size += vs; 637 } 638 639 this->require_c_string("\n"); 640 641 // Types can refer to each other in an unpredictable order. Read 642 // all the type data into type_data_. The type_offsets_ vector we 643 // just initialized provides indexes into type_data_. 644 645 this->type_pos_ = this->stream_->pos(); 646 const char* type_data; 647 if (!this->stream_->peek(total_type_size, &type_data)) 648 return false; 649 this->type_data_ = std::string(type_data, total_type_size); 650 this->advance(total_type_size); 651 652 this->types_.resize(maxp1, NULL); 653 654 // Parse all the exported types now, so that the names are properly 655 // bound and visible to the parser. Parse unexported types lazily. 656 657 // Start at 1 because there is no type 0. 658 for (int i = 1; i < exportedp1; i++) 659 { 660 // We may have already parsed this type when we parsed an 661 // earlier type. 662 Type* type = this->types_[i]; 663 if (type == NULL) 664 { 665 if (!this->parse_type(i)) 666 return false; 667 type = this->types_[i]; 668 go_assert(type != NULL); 669 } 670 Named_type* nt = type->named_type(); 671 if (nt == NULL) 672 { 673 go_error_at(this->location_, 674 "error in import data: exported unnamed type %d", 675 i); 676 return false; 677 } 678 nt->set_is_visible(); 679 if (this->add_to_globals_) 680 this->gogo_->add_named_type(nt); 681 } 682 683 return true; 684 } 685 686 void 687 Import::finalize_methods() 688 { 689 Finalize_methods finalizer(this->gogo_); 690 Unordered_set(Type*) real_for_named; 691 for (size_t i = 1; i < this->types_.size(); i++) 692 { 693 Type* type = this->types_[i]; 694 if (type != NULL && type->named_type() != NULL) 695 { 696 finalizer.type(type); 697 698 // If the real type is a struct type, we don't want to 699 // finalize its methods. For a named type defined as a 700 // struct type, we only want to finalize the methods of the 701 // named type. This is like Finalize_methods::type. 702 Type* real_type = type->named_type()->real_type(); 703 if (real_type->struct_type() != NULL) 704 real_for_named.insert(real_type); 705 } 706 } 707 for (size_t i = 1; i < this->types_.size(); i++) 708 { 709 Type* type = this->types_[i]; 710 if (type != NULL 711 && type->named_type() == NULL 712 && real_for_named.find(type) == real_for_named.end()) 713 finalizer.type(type); 714 } 715 } 716 717 // Import a constant. 718 719 void 720 Import::import_const() 721 { 722 std::string name; 723 Type* type; 724 Expression* expr; 725 Named_constant::import_const(this, &name, &type, &expr); 726 Typed_identifier tid(name, type, this->location_); 727 Named_object* no = this->package_->add_constant(tid, expr); 728 if (this->add_to_globals_) 729 this->gogo_->add_dot_import_object(no); 730 } 731 732 // Import a type. 733 734 void 735 Import::import_type() 736 { 737 if (this->version_ >= EXPORT_FORMAT_V3) 738 { 739 if (!this->stream_->saw_error()) 740 { 741 go_error_at(this->location_, 742 "error in import data at %d: old type syntax", 743 this->stream_->pos()); 744 this->stream_->set_saw_error(); 745 } 746 return; 747 } 748 749 Named_type* type; 750 Named_type::import_named_type(this, &type); 751 752 // The named type has been added to the package by the type import 753 // process. Here we need to make it visible to the parser, and it 754 // to the global bindings if necessary. 755 type->set_is_visible(); 756 757 if (this->add_to_globals_) 758 this->gogo_->add_named_type(type); 759 } 760 761 // Import a variable. 762 763 void 764 Import::import_var() 765 { 766 std::string name; 767 Package* vpkg; 768 bool is_exported; 769 Type* type; 770 if (!Variable::import_var(this, &name, &vpkg, &is_exported, &type)) 771 return; 772 if (vpkg == NULL) 773 vpkg = this->package_; 774 if (!is_exported) 775 name = '.' + vpkg->pkgpath() + '.' + name; 776 Variable* var = new Variable(type, NULL, true, false, false, 777 this->location_); 778 Named_object* no; 779 no = vpkg->add_variable(name, var); 780 if (this->add_to_globals_ && vpkg == this->package_) 781 this->gogo_->add_dot_import_object(no); 782 } 783 784 // Import a function into PACKAGE. PACKAGE is normally 785 // THIS->PACKAGE_, but it will be different for a method associated 786 // with a type defined in a different package. 787 788 void 789 Import::import_func(Package* package) 790 { 791 std::string name; 792 Package* fpkg; 793 bool is_exported; 794 Typed_identifier* receiver; 795 Typed_identifier_list* parameters; 796 Typed_identifier_list* results; 797 bool is_varargs; 798 bool nointerface; 799 std::string asm_name; 800 std::string body; 801 if (!Function::import_func(this, &name, &fpkg, &is_exported, &receiver, 802 ¶meters, &results, &is_varargs, &nointerface, 803 &asm_name, &body)) 804 return; 805 if (fpkg == NULL) 806 fpkg = package; 807 if (!is_exported) 808 name = '.' + fpkg->pkgpath() + '.' + name; 809 Function_type *fntype = Type::make_function_type(receiver, parameters, 810 results, this->location_); 811 if (is_varargs) 812 fntype->set_is_varargs(); 813 814 Location loc = this->location_; 815 Named_object* no; 816 if (fntype->is_method()) 817 { 818 Type* rtype = receiver->type(); 819 820 // We may still be reading the definition of RTYPE, so we have 821 // to be careful to avoid calling base or convert. If RTYPE is 822 // a named type or a forward declaration, then we know that it 823 // is not a pointer, because we are reading a method on RTYPE 824 // and named pointers can't have methods. 825 826 if (rtype->classification() == Type::TYPE_POINTER) 827 rtype = rtype->points_to(); 828 829 if (rtype->is_error_type()) 830 return; 831 else if (rtype->named_type() != NULL) 832 no = rtype->named_type()->add_method_declaration(name, fpkg, fntype, 833 loc); 834 else if (rtype->forward_declaration_type() != NULL) 835 no = rtype->forward_declaration_type()->add_method_declaration(name, 836 fpkg, 837 fntype, 838 loc); 839 else 840 go_unreachable(); 841 } 842 else 843 { 844 no = fpkg->add_function_declaration(name, fntype, loc); 845 if (this->add_to_globals_ && fpkg == package) 846 this->gogo_->add_dot_import_object(no); 847 } 848 849 if (nointerface) 850 no->func_declaration_value()->set_nointerface(); 851 if (!asm_name.empty()) 852 no->func_declaration_value()->set_asm_name(asm_name); 853 if (!body.empty() && !no->func_declaration_value()->has_imported_body()) 854 no->func_declaration_value()->set_imported_body(this, body); 855 } 856 857 // Read a type definition and initialize the entry in this->types_. 858 // This parses the type definition saved by read_types earlier. This 859 // returns true on success, false on failure. 860 861 bool 862 Import::parse_type(int i) 863 { 864 go_assert(i >= 0 && static_cast<size_t>(i) < this->types_.size()); 865 go_assert(this->types_[i] == NULL); 866 size_t offset = this->type_offsets_[i].first; 867 size_t len = this->type_offsets_[i].second; 868 869 Stream* orig_stream = this->stream_; 870 871 Stream_from_string_ref stream(this->type_data_, offset, len); 872 stream.set_pos(this->type_pos_ + offset); 873 this->stream_ = &stream; 874 875 this->require_c_string("type "); 876 std::string str = this->read_identifier(); 877 int id; 878 if (!this->string_to_int(str, false, &id)) 879 { 880 this->stream_ = orig_stream; 881 return false; 882 } 883 if (i != id) 884 { 885 go_error_at(this->location_, 886 ("error in import data at %d: " 887 "type ID mismatch: got %d, want %d"), 888 stream.pos(), id, i); 889 this->stream_ = orig_stream; 890 return false; 891 } 892 893 this->require_c_string(" "); 894 if (stream.peek_char() == '"') 895 { 896 stream.advance(1); 897 Type* type = this->read_named_type(i); 898 if (type->is_error_type()) 899 { 900 this->stream_ = orig_stream; 901 return false; 902 } 903 } 904 else 905 { 906 Type* type = Type::import_type(this); 907 if (type->is_error_type()) 908 { 909 this->stream_ = orig_stream; 910 return false; 911 } 912 this->types_[i] = type; 913 914 this->require_c_string("\n"); 915 } 916 917 this->stream_ = orig_stream; 918 return true; 919 } 920 921 // Read a type in the import stream. This records the type by the 922 // type index. If the type is named (which can only happen with older 923 // export formats), it registers the name, but marks it as invisible. 924 925 Type* 926 Import::read_type() 927 { 928 Stream* stream = this->stream_; 929 this->require_c_string("<type "); 930 931 std::string number; 932 int c; 933 while (true) 934 { 935 c = stream->get_char(); 936 if (c != '-' && (c < '0' || c > '9')) 937 break; 938 number += c; 939 } 940 941 int index; 942 if (!this->string_to_int(number, true, &index)) 943 return Type::make_error_type(); 944 945 if (c == '>') 946 { 947 // A reference to a type defined earlier. 948 bool parsed; 949 return this->type_for_index(index, "import data", stream->pos(), 950 &parsed); 951 } 952 953 if (this->version_ >= EXPORT_FORMAT_V3) 954 { 955 if (!stream->saw_error()) 956 go_error_at(this->location_, 957 "error in import data at %d: expected %<>%>", 958 stream->pos()); 959 stream->set_saw_error(); 960 return Type::make_error_type(); 961 } 962 963 if (c != ' ') 964 { 965 if (!stream->saw_error()) 966 go_error_at(this->location_, 967 "error in import data at %d: expected %< %> or %<>%>", 968 stream->pos()); 969 stream->set_saw_error(); 970 stream->advance(1); 971 return Type::make_error_type(); 972 } 973 974 if (index <= 0 975 || (static_cast<size_t>(index) < this->types_.size() 976 && this->types_[index] != NULL)) 977 { 978 go_error_at(this->location_, 979 "error in import data at %d: type index already defined", 980 stream->pos()); 981 stream->set_saw_error(); 982 return Type::make_error_type(); 983 } 984 985 if (static_cast<size_t>(index) >= this->types_.size()) 986 { 987 int newsize = std::max(static_cast<size_t>(index) + 1, 988 this->types_.size() * 2); 989 this->types_.resize(newsize, NULL); 990 } 991 992 if (stream->peek_char() != '"') 993 { 994 Type* type = Type::import_type(this); 995 this->require_c_string(">"); 996 this->types_[index] = type; 997 return type; 998 } 999 1000 stream->advance(1); 1001 1002 Type* type = this->read_named_type(index); 1003 1004 this->require_c_string(">"); 1005 1006 return type; 1007 } 1008 1009 // Read a named type from the import stream and store it in 1010 // this->types_[index]. The stream should be positioned immediately 1011 // after the '"' that starts the name. 1012 1013 Type* 1014 Import::read_named_type(int index) 1015 { 1016 Stream* stream = this->stream_; 1017 std::string type_name; 1018 int c; 1019 while ((c = stream->get_char()) != '"') 1020 type_name += c; 1021 1022 // If this type is in the package we are currently importing, the 1023 // name will be .PKGPATH.NAME or simply NAME with no dots. 1024 // Otherwise, a non-hidden symbol will be PKGPATH.NAME and a hidden 1025 // symbol will be .PKGPATH.NAME. 1026 std::string pkgpath; 1027 if (type_name.find('.') != std::string::npos) 1028 { 1029 size_t start = 0; 1030 if (type_name[0] == '.') 1031 start = 1; 1032 size_t dot = type_name.rfind('.'); 1033 pkgpath = type_name.substr(start, dot - start); 1034 if (type_name[0] != '.') 1035 type_name.erase(0, dot + 1); 1036 } 1037 1038 this->require_c_string(" "); 1039 1040 // The package name may follow. This is the name of the package in 1041 // the package clause of that package. The type name will include 1042 // the pkgpath, which may be different. 1043 std::string package_name; 1044 if (stream->peek_char() == '"') 1045 { 1046 stream->advance(1); 1047 while ((c = stream->get_char()) != '"') 1048 package_name += c; 1049 this->require_c_string(" "); 1050 } 1051 1052 bool is_alias = false; 1053 if (this->match_c_string("= ")) 1054 { 1055 stream->advance(2); 1056 is_alias = true; 1057 } 1058 1059 // Declare the type in the appropriate package. If we haven't seen 1060 // it before, mark it as invisible. We declare it before we read 1061 // the actual definition of the type, since the definition may refer 1062 // to the type itself. 1063 Package* package; 1064 if (pkgpath.empty() || pkgpath == this->gogo_->pkgpath()) 1065 package = this->package_; 1066 else 1067 { 1068 package = this->gogo_->register_package(pkgpath, "", 1069 Linemap::unknown_location()); 1070 if (!package_name.empty()) 1071 package->set_package_name(package_name, this->location()); 1072 } 1073 1074 Named_object* no = package->bindings()->lookup(type_name); 1075 if (no == NULL) 1076 no = package->add_type_declaration(type_name, this->location_); 1077 else if (!no->is_type_declaration() && !no->is_type()) 1078 { 1079 go_error_at(this->location_, "imported %<%s.%s%> both type and non-type", 1080 pkgpath.c_str(), Gogo::message_name(type_name).c_str()); 1081 stream->set_saw_error(); 1082 return Type::make_error_type(); 1083 } 1084 else 1085 go_assert(no->package() == package); 1086 1087 if (this->types_[index] == NULL) 1088 { 1089 if (no->is_type_declaration()) 1090 { 1091 // FIXME: It's silly to make a forward declaration every time. 1092 this->types_[index] = Type::make_forward_declaration(no); 1093 } 1094 else 1095 { 1096 go_assert(no->is_type()); 1097 this->types_[index] = no->type_value(); 1098 } 1099 } 1100 1101 // If there is no type definition, then this is just a forward 1102 // declaration of a type defined in some other file. 1103 Type* type; 1104 if (this->match_c_string(">") || this->match_c_string("\n")) 1105 type = this->types_[index]; 1106 else 1107 { 1108 if (no->is_type_declaration()) 1109 { 1110 // We can define the type now. 1111 1112 type = this->read_type(); 1113 1114 no = package->add_type(type_name, type, this->location_); 1115 Named_type* ntype = no->type_value(); 1116 1117 // This type has not yet been imported. 1118 ntype->clear_is_visible(); 1119 1120 if (is_alias) 1121 ntype->set_is_alias(); 1122 1123 if (!type->is_undefined() && type->interface_type() != NULL) 1124 this->gogo_->record_interface_type(type->interface_type()); 1125 1126 type = ntype; 1127 } 1128 else if (no->is_type()) 1129 { 1130 // We have seen this type before. 1131 type = no->type_value(); 1132 1133 // Don't change the visibility of the existing type. 1134 1135 // For older export versions, we need to skip the type 1136 // definition in the stream. 1137 if (this->version_ < EXPORT_FORMAT_V3) 1138 this->read_type(); 1139 } 1140 else 1141 go_unreachable(); 1142 1143 this->types_[index] = type; 1144 1145 // Read the type methods. 1146 if (this->match_c_string("\n")) 1147 { 1148 this->advance(1); 1149 while (this->match_c_string(" func")) 1150 { 1151 this->advance(1); 1152 this->import_func(package); 1153 } 1154 } 1155 } 1156 1157 return type; 1158 } 1159 1160 // Return the type given an index. Set *PARSED if we parsed it here. 1161 1162 Type* 1163 Import::type_for_index(int index, const std::string& input_name, 1164 size_t input_offset, bool* parsed) 1165 { 1166 *parsed = false; 1167 if (index >= 0 && !this->type_data_.empty()) 1168 { 1169 if (static_cast<size_t>(index) >= this->type_offsets_.size()) 1170 { 1171 go_error_at(this->location_, 1172 "error in %s at %lu: bad type index %d, max %d", 1173 input_name.c_str(), 1174 static_cast<unsigned long>(input_offset), 1175 index, static_cast<int>(this->type_offsets_.size())); 1176 return Type::make_error_type(); 1177 } 1178 1179 if (this->types_[index] == NULL) 1180 { 1181 if (!this->parse_type(index)) 1182 return Type::make_error_type(); 1183 *parsed = true; 1184 } 1185 } 1186 1187 if (index < 0 1188 ? (static_cast<size_t>(- index) >= this->builtin_types_.size() 1189 || this->builtin_types_[- index] == NULL) 1190 : (static_cast<size_t>(index) >= this->types_.size() 1191 || this->types_[index] == NULL)) 1192 { 1193 go_error_at(this->location_, 1194 "error in %s at %lu: bad type index %d", 1195 input_name.c_str(), 1196 static_cast<unsigned long>(input_offset), index); 1197 return Type::make_error_type(); 1198 } 1199 1200 return index < 0 ? this->builtin_types_[- index] : this->types_[index]; 1201 } 1202 1203 // Read an escape note. 1204 1205 std::string 1206 Import::read_escape() 1207 { 1208 if (this->match_c_string(" <esc:")) 1209 { 1210 Stream* stream = this->stream_; 1211 this->require_c_string(" <esc:"); 1212 1213 std::string escape = "esc:"; 1214 int c; 1215 while (true) 1216 { 1217 c = stream->get_char(); 1218 if (c != 'x' && !ISXDIGIT(c)) 1219 break; 1220 escape += c; 1221 } 1222 1223 if (c != '>') 1224 { 1225 go_error_at(this->location(), 1226 ("error in import data at %d: " 1227 "expect %< %> or %<>%>, got %c"), 1228 stream->pos(), c); 1229 stream->set_saw_error(); 1230 stream->advance(1); 1231 escape = Escape_note::make_tag(Node::ESCAPE_UNKNOWN); 1232 } 1233 return escape; 1234 } 1235 else 1236 return Escape_note::make_tag(Node::ESCAPE_UNKNOWN); 1237 } 1238 1239 1240 // Register the builtin types. 1241 1242 void 1243 Import::register_builtin_types(Gogo* gogo) 1244 { 1245 this->register_builtin_type(gogo, "int8", BUILTIN_INT8); 1246 this->register_builtin_type(gogo, "int16", BUILTIN_INT16); 1247 this->register_builtin_type(gogo, "int32", BUILTIN_INT32); 1248 this->register_builtin_type(gogo, "int64", BUILTIN_INT64); 1249 this->register_builtin_type(gogo, "uint8", BUILTIN_UINT8); 1250 this->register_builtin_type(gogo, "uint16", BUILTIN_UINT16); 1251 this->register_builtin_type(gogo, "uint32", BUILTIN_UINT32); 1252 this->register_builtin_type(gogo, "uint64", BUILTIN_UINT64); 1253 this->register_builtin_type(gogo, "float32", BUILTIN_FLOAT32); 1254 this->register_builtin_type(gogo, "float64", BUILTIN_FLOAT64); 1255 this->register_builtin_type(gogo, "complex64", BUILTIN_COMPLEX64); 1256 this->register_builtin_type(gogo, "complex128", BUILTIN_COMPLEX128); 1257 this->register_builtin_type(gogo, "int", BUILTIN_INT); 1258 this->register_builtin_type(gogo, "uint", BUILTIN_UINT); 1259 this->register_builtin_type(gogo, "uintptr", BUILTIN_UINTPTR); 1260 this->register_builtin_type(gogo, "bool", BUILTIN_BOOL); 1261 this->register_builtin_type(gogo, "string", BUILTIN_STRING); 1262 this->register_builtin_type(gogo, "error", BUILTIN_ERROR); 1263 this->register_builtin_type(gogo, "byte", BUILTIN_BYTE); 1264 this->register_builtin_type(gogo, "rune", BUILTIN_RUNE); 1265 } 1266 1267 // Register a single builtin type. 1268 1269 void 1270 Import::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code) 1271 { 1272 Named_object* named_object = gogo->lookup_global(name); 1273 go_assert(named_object != NULL && named_object->is_type()); 1274 int index = - static_cast<int>(code); 1275 go_assert(index > 0 1276 && static_cast<size_t>(index) < this->builtin_types_.size()); 1277 this->builtin_types_[index] = named_object->type_value(); 1278 } 1279 1280 // Characters that stop read_identifier. We base this on the 1281 // characters that stop an identifier, without worrying about 1282 // characters that are permitted in an identifier. That lets us skip 1283 // UTF-8 parsing. 1284 static const char * const identifier_stop = " \n;:,()[]"; 1285 1286 // Read an identifier from the stream. 1287 1288 std::string 1289 Import::read_identifier() 1290 { 1291 std::string ret; 1292 Stream* stream = this->stream_; 1293 int c; 1294 while (true) 1295 { 1296 c = stream->peek_char(); 1297 if (c == -1 || strchr(identifier_stop, c) != NULL) 1298 break; 1299 1300 // FIXME: Probably we shouldn't accept '.', but that might break 1301 // some existing imports. 1302 if (c == '.' && stream->match_c_string("...")) 1303 break; 1304 1305 ret += c; 1306 stream->advance(1); 1307 } 1308 return ret; 1309 } 1310 1311 // Read a possibly qualified identifier from IMP. The qualification 1312 // is <pID>, where ID is a package number. If the name has a leading 1313 // '.', it is not exported; otherwise, it is. Set *NAME, *PKG and 1314 // *IS_EXPORTED. Reports whether the read succeeded. 1315 1316 bool 1317 Import::read_qualified_identifier(Import_expression* imp, std::string* name, 1318 Package** pkg, bool* is_exported) 1319 { 1320 *pkg = NULL; 1321 if (imp->match_c_string("<p")) 1322 { 1323 imp->advance(2); 1324 char buf[50]; 1325 char *pbuf = &buf[0]; 1326 while (true) 1327 { 1328 int next = imp->peek_char(); 1329 if (next == -1 || static_cast<size_t>(pbuf - buf) >= sizeof buf - 1) 1330 return false; 1331 if (next == '>') 1332 { 1333 imp->advance(1); 1334 break; 1335 } 1336 *pbuf = static_cast<char>(next); 1337 ++pbuf; 1338 imp->advance(1); 1339 } 1340 1341 *pbuf = '\0'; 1342 char *end; 1343 long index = strtol(buf, &end, 10); 1344 if (*end != '\0' 1345 || index <= 0 1346 || static_cast<size_t>(index) > imp->max_package_index()) 1347 return false; 1348 1349 *pkg = imp->package_at_index(index); 1350 go_assert(*pkg != NULL); 1351 } 1352 1353 *is_exported = true; 1354 if (imp->match_c_string(".")) 1355 { 1356 imp->advance(1); 1357 *is_exported = false; 1358 } 1359 1360 *name = imp->read_identifier(); 1361 1362 return !name->empty(); 1363 } 1364 1365 // Read a name from the stream. 1366 1367 std::string 1368 Import::read_name() 1369 { 1370 std::string ret = this->read_identifier(); 1371 if (ret == "?") 1372 ret.clear(); 1373 return ret; 1374 } 1375 1376 // Read LENGTH bytes from the stream. 1377 1378 std::string 1379 Import::read(size_t length) 1380 { 1381 const char* data; 1382 if (!this->stream_->peek(length, &data)) 1383 { 1384 if (!this->stream_->saw_error()) 1385 go_error_at(this->location_, "import error at %d: expected %d bytes", 1386 this->stream_->pos(), static_cast<int>(length)); 1387 this->stream_->set_saw_error(); 1388 return ""; 1389 } 1390 this->advance(length); 1391 return std::string(data, length); 1392 } 1393 1394 // Turn a string into a integer with appropriate error handling. 1395 1396 bool 1397 Import::string_to_int(const std::string &s, bool is_neg_ok, int* ret) 1398 { 1399 char* end; 1400 long prio = strtol(s.c_str(), &end, 10); 1401 if (*end != '\0' || prio > 0x7fffffff || (prio < 0 && !is_neg_ok)) 1402 { 1403 go_error_at(this->location_, "invalid integer in import data at %d", 1404 this->stream_->pos()); 1405 this->stream_->set_saw_error(); 1406 return false; 1407 } 1408 *ret = prio; 1409 return true; 1410 } 1411 1412 // Class Import::Stream. 1413 1414 Import::Stream::Stream() 1415 : pos_(0), saw_error_(false) 1416 { 1417 } 1418 1419 Import::Stream::~Stream() 1420 { 1421 } 1422 1423 // Return the next character to come from the stream. 1424 1425 int 1426 Import::Stream::peek_char() 1427 { 1428 const char* read; 1429 if (!this->do_peek(1, &read)) 1430 return -1; 1431 // Make sure we return an unsigned char, so that we don't get 1432 // confused by \xff. 1433 unsigned char ret = *read; 1434 return ret; 1435 } 1436 1437 // Return true if the next LENGTH characters from the stream match 1438 // BYTES 1439 1440 bool 1441 Import::Stream::match_bytes(const char* bytes, size_t length) 1442 { 1443 const char* read; 1444 if (!this->do_peek(length, &read)) 1445 return false; 1446 return memcmp(bytes, read, length) == 0; 1447 } 1448 1449 // Require that the next LENGTH bytes from the stream match BYTES. 1450 1451 void 1452 Import::Stream::require_bytes(Location location, const char* bytes, 1453 size_t length) 1454 { 1455 const char* read; 1456 if (!this->do_peek(length, &read) 1457 || memcmp(bytes, read, length) != 0) 1458 { 1459 if (!this->saw_error_) 1460 go_error_at(location, "import error at %d: expected %<%.*s%>", 1461 this->pos(), static_cast<int>(length), bytes); 1462 this->saw_error_ = true; 1463 return; 1464 } 1465 this->advance(length); 1466 } 1467 1468 // Class Stream_from_file. 1469 1470 Stream_from_file::Stream_from_file(int fd) 1471 : fd_(fd), data_() 1472 { 1473 if (lseek(fd, 0, SEEK_SET) != 0) 1474 { 1475 go_fatal_error(Linemap::unknown_location(), "lseek failed: %m"); 1476 this->set_saw_error(); 1477 } 1478 } 1479 1480 Stream_from_file::~Stream_from_file() 1481 { 1482 close(this->fd_); 1483 } 1484 1485 // Read next bytes. 1486 1487 bool 1488 Stream_from_file::do_peek(size_t length, const char** bytes) 1489 { 1490 if (this->data_.length() <= length) 1491 { 1492 *bytes = this->data_.data(); 1493 return true; 1494 } 1495 1496 this->data_.resize(length); 1497 ssize_t got = ::read(this->fd_, &this->data_[0], length); 1498 1499 if (got < 0) 1500 { 1501 if (!this->saw_error()) 1502 go_fatal_error(Linemap::unknown_location(), "read failed: %m"); 1503 this->set_saw_error(); 1504 return false; 1505 } 1506 1507 if (lseek(this->fd_, - got, SEEK_CUR) != 0) 1508 { 1509 if (!this->saw_error()) 1510 go_fatal_error(Linemap::unknown_location(), "lseek failed: %m"); 1511 this->set_saw_error(); 1512 return false; 1513 } 1514 1515 if (static_cast<size_t>(got) < length) 1516 return false; 1517 1518 *bytes = this->data_.data(); 1519 return true; 1520 } 1521 1522 // Advance. 1523 1524 void 1525 Stream_from_file::do_advance(size_t skip) 1526 { 1527 if (lseek(this->fd_, skip, SEEK_CUR) != 0) 1528 { 1529 if (!this->saw_error()) 1530 go_fatal_error(Linemap::unknown_location(), "lseek failed: %m"); 1531 this->set_saw_error(); 1532 } 1533 if (!this->data_.empty()) 1534 { 1535 if (this->data_.length() < skip) 1536 this->data_.erase(0, skip); 1537 else 1538 this->data_.clear(); 1539 } 1540 } 1541 1542 // Class Import_function_body. 1543 1544 Import_function_body::Import_function_body(Gogo* gogo, 1545 Import* imp, 1546 Named_object* named_object, 1547 const std::string& body, 1548 size_t off, 1549 Block* block, 1550 int indent) 1551 : gogo_(gogo), imp_(imp), named_object_(named_object), body_(body), 1552 off_(off), indent_(indent), temporaries_(), labels_(), 1553 saw_error_(false) 1554 { 1555 this->blocks_.push_back(block); 1556 } 1557 1558 Import_function_body::~Import_function_body() 1559 { 1560 // At this point we should be left with the original outer block only. 1561 go_assert(saw_errors() || this->blocks_.size() == 1); 1562 } 1563 1564 // The name of the function we are parsing. 1565 1566 const std::string& 1567 Import_function_body::name() const 1568 { 1569 return this->named_object_->name(); 1570 } 1571 1572 // Class Import_function_body. 1573 1574 // Require that the next bytes match STR, issuing an error if not. 1575 // Advance past the string. 1576 1577 void 1578 Import_function_body::require_c_string(const char* str) 1579 { 1580 if (!this->match_c_string(str)) 1581 { 1582 if (!this->saw_error_) 1583 go_error_at(this->location(), 1584 "invalid export data for %qs: expected %qs at %lu", 1585 this->name().c_str(), str, 1586 static_cast<unsigned long>(this->off_)); 1587 this->saw_error_ = true; 1588 return; 1589 } 1590 this->advance(strlen(str)); 1591 } 1592 1593 // Read an identifier. 1594 1595 std::string 1596 Import_function_body::read_identifier() 1597 { 1598 size_t start = this->off_; 1599 for (size_t i = start; i < this->body_.length(); i++) 1600 { 1601 int c = static_cast<unsigned char>(this->body_[i]); 1602 if (strchr(identifier_stop, c) != NULL) 1603 { 1604 this->off_ = i; 1605 return this->body_.substr(start, i - start); 1606 } 1607 1608 // FIXME: Probably we shouldn't accept '.', but that might break 1609 // some existing imports. 1610 if (c == '.' 1611 && i + 2 < this->body_.length() 1612 && this->body_[i + 1] == '.' 1613 && this->body_[i + 2] == '.') 1614 { 1615 this->off_ = i; 1616 return this->body_.substr(start, i - start); 1617 } 1618 } 1619 this->off_ = this->body_.length(); 1620 return this->body_.substr(start); 1621 } 1622 1623 // Read a type. 1624 1625 Type* 1626 Import_function_body::read_type() 1627 { 1628 this->require_c_string("<type "); 1629 size_t start = this->off_; 1630 size_t i; 1631 int c = '\0'; 1632 for (i = start; i < this->body_.length(); ++i) 1633 { 1634 c = static_cast<unsigned char>(this->body_[i]); 1635 if (c != '-' && (c < '0' || c > '9')) 1636 break; 1637 } 1638 this->off_ = i + 1; 1639 1640 char *end; 1641 std::string num = this->body_.substr(start, i - start); 1642 long val = strtol(num.c_str(), &end, 10); 1643 if (*end != '\0' || val > 0x7fffffff) 1644 { 1645 if (!this->saw_error_) 1646 go_error_at(this->location(), 1647 "invalid export data for %qs: expected integer at %lu", 1648 this->name().c_str(), 1649 static_cast<unsigned long>(start)); 1650 this->saw_error_ = true; 1651 return Type::make_error_type(); 1652 } 1653 1654 if (c != '>') 1655 { 1656 if (!this->saw_error_) 1657 go_error_at(this->location(), 1658 "invalid export data for %qs: expected %<>%> at %lu", 1659 this->name().c_str(), 1660 static_cast<unsigned long>(i)); 1661 this->saw_error_ = true; 1662 return Type::make_error_type(); 1663 } 1664 1665 bool parsed; 1666 Type* type = this->imp_->type_for_index(static_cast<int>(val), this->name(), 1667 static_cast<unsigned long>(start), 1668 &parsed); 1669 1670 // If we just read this type's information, its methods will not 1671 // have been finalized. Do that now. 1672 if (parsed) 1673 this->gogo_->finalize_methods_for_type(type); 1674 1675 return type; 1676 } 1677 1678 // Return the next size to use for a vector mapping indexes to values. 1679 1680 size_t 1681 Import_function_body::next_size(size_t have) 1682 { 1683 if (have == 0) 1684 return 8; 1685 else if (have < 256) 1686 return have * 2; 1687 else 1688 return have + 64; 1689 } 1690 1691 // Record the index of a temporary statement. 1692 1693 void 1694 Import_function_body::record_temporary(Temporary_statement* temp, 1695 unsigned int idx) 1696 { 1697 size_t have = this->temporaries_.size(); 1698 while (static_cast<size_t>(idx) >= have) 1699 { 1700 size_t want = Import_function_body::next_size(have); 1701 this->temporaries_.resize(want, NULL); 1702 have = want; 1703 } 1704 this->temporaries_[idx] = temp; 1705 } 1706 1707 // Return a temporary statement given an index. 1708 1709 Temporary_statement* 1710 Import_function_body::temporary_statement(unsigned int idx) 1711 { 1712 if (static_cast<size_t>(idx) >= this->temporaries_.size()) 1713 return NULL; 1714 return this->temporaries_[idx]; 1715 } 1716 1717 // Return an unnamed label given an index, defining the label if we 1718 // haven't seen it already. 1719 1720 Unnamed_label* 1721 Import_function_body::unnamed_label(unsigned int idx, Location loc) 1722 { 1723 size_t have = this->labels_.size(); 1724 while (static_cast<size_t>(idx) >= have) 1725 { 1726 size_t want = Import_function_body::next_size(have); 1727 this->labels_.resize(want, NULL); 1728 have = want; 1729 } 1730 Unnamed_label* label = this->labels_[idx]; 1731 if (label == NULL) 1732 { 1733 label = new Unnamed_label(loc); 1734 this->labels_[idx] = label; 1735 } 1736 return label; 1737 }