diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 76689a3b50a..fa708bceae7 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -e32e9aaee598eeb43f9616cf6ca1d11acaa9d167 +0494dc5737f0c89ad6f45e04e8313e4161678861 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/export.cc b/gcc/go/gofrontend/export.cc index 27b76801d5c..db57ab58850 100644 --- a/gcc/go/gofrontend/export.cc +++ b/gcc/go/gofrontend/export.cc @@ -26,14 +26,18 @@ const int Export::magic_len; // Current version magic string. const char Export::cur_magic[Export::magic_len] = { - 'v', '2', ';', '\n' + 'v', '3', ';', '\n' }; -// Magic string for previous version (still supported) +// Magic strings for previous versions (still supported). const char Export::v1_magic[Export::magic_len] = { 'v', '1', ';', '\n' }; +const char Export::v2_magic[Export::magic_len] = + { + 'v', '2', ';', '\n' + }; const int Export::checksum_len; @@ -147,7 +151,7 @@ Export::export_globals(const std::string& package_name, // The package name. this->write_c_string("package "); this->write_string(package_name); - this->write_c_string(";\n"); + this->write_c_string("\n"); // The prefix or package path, used for all global symbols. if (prefix.empty()) @@ -161,7 +165,7 @@ Export::export_globals(const std::string& package_name, this->write_c_string("prefix "); this->write_string(prefix); } - this->write_c_string(";\n"); + this->write_c_string("\n"); this->write_packages(packages); @@ -191,7 +195,7 @@ Export::export_globals(const std::string& package_name, dig = c & 0xf; s += dig < 10 ? '0' + dig : 'A' + dig - 10; } - s += ";\n"; + s += "\n"; this->stream_->write_checksum(s); } @@ -233,7 +237,7 @@ Export::write_packages(const std::map& packages) this->write_string((*p)->pkgpath()); this->write_c_string(" "); this->write_string((*p)->pkgpath_symbol()); - this->write_c_string(";\n"); + this->write_c_string("\n"); } } @@ -271,7 +275,7 @@ Export::write_imports(const std::map& imports) this->write_string(p->second->pkgpath()); this->write_c_string(" \""); this->write_string(p->first); - this->write_c_string("\";\n"); + this->write_c_string("\"\n"); this->packages_.insert(p->second); } @@ -347,7 +351,7 @@ Export::write_imported_init_fns(const std::string& package_name, if (imported_init_fns.empty()) { - this->write_c_string(";\n"); + this->write_c_string("\n"); return; } @@ -394,7 +398,7 @@ Export::write_imported_init_fns(const std::string& package_name, it->second.push_back(ii->init_name()); } } - this->write_c_string(";\n"); + this->write_c_string("\n"); // Create the init graph. Start by populating the graph with // all the edges we inherited from imported packages. @@ -494,7 +498,7 @@ Export::write_imported_init_fns(const std::string& package_name, this->write_unsigned(sink); } } - this->write_c_string(";\n"); + this->write_c_string("\n"); } // Write a name to the export stream. diff --git a/gcc/go/gofrontend/export.h b/gcc/go/gofrontend/export.h index 136567725a5..b08bf851318 100644 --- a/gcc/go/gofrontend/export.h +++ b/gcc/go/gofrontend/export.h @@ -57,7 +57,8 @@ enum Export_data_version { EXPORT_FORMAT_UNKNOWN = 0, EXPORT_FORMAT_V1 = 1, EXPORT_FORMAT_V2 = 2, - EXPORT_FORMAT_CURRENT = EXPORT_FORMAT_V2 + EXPORT_FORMAT_V3 = 3, + EXPORT_FORMAT_CURRENT = EXPORT_FORMAT_V3 }; // This class manages exporting Go declarations. It handles the main @@ -119,9 +120,10 @@ class Export : public String_dump // Size of export data magic string (which includes version number). static const int magic_len = 4; - // Magic strings (current version and older v1 version). + // Magic strings (current version and older versions). static const char cur_magic[magic_len]; static const char v1_magic[magic_len]; + static const char v2_magic[magic_len]; // The length of the checksum string. static const int checksum_len = 20; diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index dd6733fab8b..d07068d49ac 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -5391,7 +5391,7 @@ Function::export_func_with_type(Export* exp, const std::string& name, exp->write_c_string(")"); } } - exp->write_c_string(";\n"); + exp->write_c_string("\n"); } // Import a function. @@ -5498,7 +5498,8 @@ Function::import_func(Import* imp, std::string* pname, imp->require_c_string(")"); } } - imp->require_c_string(";\n"); + imp->require_semicolon_if_old_version(); + imp->require_c_string("\n"); *presults = results; } @@ -6885,7 +6886,7 @@ Variable::export_var(Export* exp, const std::string& name) const exp->write_string(name); exp->write_c_string(" "); exp->write_type(this->type()); - exp->write_c_string(";\n"); + exp->write_c_string("\n"); } // Import a variable. @@ -6897,7 +6898,8 @@ Variable::import_var(Import* imp, std::string* pname, Type** ptype) *pname = imp->read_identifier(); imp->require_c_string(" "); *ptype = imp->read_type(); - imp->require_c_string(";\n"); + imp->require_semicolon_if_old_version(); + imp->require_c_string("\n"); } // Convert a variable to the backend representation. @@ -7089,7 +7091,7 @@ Named_constant::export_const(Export* exp, const std::string& name) const } exp->write_c_string("= "); this->expr()->export_expression(exp); - exp->write_c_string(";\n"); + exp->write_c_string("\n"); } // Import a constant. @@ -7110,7 +7112,8 @@ Named_constant::import_const(Import* imp, std::string* pname, Type** ptype, } imp->require_c_string("= "); *pexpr = Expression::import_expression(imp); - imp->require_c_string(";\n"); + imp->require_semicolon_if_old_version(); + imp->require_c_string("\n"); } // Get the backend representation. diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc index f9586ac1600..ad30e6ee488 100644 --- a/gcc/go/gofrontend/import.cc +++ b/gcc/go/gofrontend/import.cc @@ -241,8 +241,9 @@ Import::find_export_data(const std::string& filename, int fd, Location location) return NULL; // Check for a file containing nothing but Go export data. - if (memcmp(buf, Export::cur_magic, Export::magic_len) == 0 || - memcmp(buf, Export::v1_magic, Export::magic_len) == 0) + if (memcmp(buf, Export::cur_magic, Export::magic_len) == 0 + || memcmp(buf, Export::v1_magic, Export::magic_len) == 0 + || memcmp(buf, Export::v2_magic, Export::magic_len) == 0) return new Stream_from_file(fd); // See if we can read this as an archive. @@ -325,6 +326,12 @@ Import::import(Gogo* gogo, const std::string& local_name, Export::magic_len); this->version_ = EXPORT_FORMAT_V1; } + else if (stream->match_bytes(Export::v2_magic, Export::magic_len)) + { + stream->require_bytes(this->location_, Export::v2_magic, + Export::magic_len); + this->version_ = EXPORT_FORMAT_V2; + } else { go_error_at(this->location_, @@ -335,7 +342,8 @@ Import::import(Gogo* gogo, const std::string& local_name, this->require_c_string("package "); std::string package_name = this->read_identifier(); - this->require_c_string(";\n"); + this->require_semicolon_if_old_version(); + this->require_c_string("\n"); std::string pkgpath; std::string pkgpath_symbol; @@ -343,7 +351,8 @@ Import::import(Gogo* gogo, const std::string& local_name, { this->advance(7); std::string unique_prefix = this->read_identifier(); - this->require_c_string(";\n"); + this->require_semicolon_if_old_version(); + this->require_c_string("\n"); pkgpath = unique_prefix + '.' + package_name; pkgpath_symbol = (Gogo::pkgpath_for_symbol(unique_prefix) + '.' + Gogo::pkgpath_for_symbol(package_name)); @@ -352,10 +361,14 @@ Import::import(Gogo* gogo, const std::string& local_name, { this->require_c_string("pkgpath "); pkgpath = this->read_identifier(); - this->require_c_string(";\n"); + this->require_semicolon_if_old_version(); + this->require_c_string("\n"); pkgpath_symbol = Gogo::pkgpath_for_symbol(pkgpath); } + if (stream->saw_error()) + return NULL; + this->package_ = gogo->add_imported_package(package_name, local_name, is_local_name_exported, pkgpath, pkgpath_symbol, @@ -418,7 +431,8 @@ Import::import(Gogo* gogo, const std::string& local_name, // load time. this->require_c_string("checksum "); stream->advance(Export::checksum_len * 2); - this->require_c_string(";\n"); + this->require_semicolon_if_old_version(); + this->require_c_string("\n"); } return this->package_; @@ -436,7 +450,8 @@ Import::read_one_package() std::string pkgpath = this->read_identifier(); this->require_c_string(" "); std::string pkgpath_symbol = this->read_identifier(); - this->require_c_string(";\n"); + this->require_semicolon_if_old_version(); + this->require_c_string("\n"); Package* p = this->gogo_->register_package(pkgpath, pkgpath_symbol, Linemap::unknown_location()); @@ -456,7 +471,9 @@ Import::read_one_import() Stream* stream = this->stream_; while (stream->peek_char() != '"') stream->advance(1); - this->require_c_string("\";\n"); + this->require_c_string("\""); + this->require_semicolon_if_old_version(); + this->require_c_string("\n"); Package* p = this->gogo_->register_package(pkgpath, "", Linemap::unknown_location()); @@ -474,7 +491,7 @@ Import::read_import_init_fns(Gogo* gogo) // to read the init_graph section. std::map init_idx; - while (!this->match_c_string(";")) + while (!this->match_c_string("\n") && !this->match_c_string(";")) { int priority = -1; @@ -499,7 +516,8 @@ Import::read_import_init_fns(Gogo* gogo) unsigned idx = init_idx.size(); init_idx[init_name] = idx; } - this->require_c_string(";\n"); + this->require_semicolon_if_old_version(); + this->require_c_string("\n"); if (this->match_c_string("init_graph")) { @@ -524,7 +542,7 @@ Import::read_import_init_fns(Gogo* gogo) // // where src + sink are init functions indices. - while (!this->match_c_string(";")) + while (!this->match_c_string("\n") && !this->match_c_string(";")) { this->require_c_string(" "); std::string src_string = this->read_identifier(); @@ -543,7 +561,8 @@ Import::read_import_init_fns(Gogo* gogo) ii_src->record_precursor_fcn(ii_sink->init_name()); } - this->require_c_string(";\n"); + this->require_semicolon_if_old_version(); + this->require_c_string("\n"); } } @@ -967,7 +986,7 @@ Import::read_identifier() while (true) { c = stream->peek_char(); - if (c == -1 || c == ' ' || c == ';') + if (c == -1 || c == ' ' || c == '\n' || c == ';') break; ret += c; stream->advance(1); diff --git a/gcc/go/gofrontend/import.h b/gcc/go/gofrontend/import.h index aab4b899ca2..84f5fc7eb86 100644 --- a/gcc/go/gofrontend/import.h +++ b/gcc/go/gofrontend/import.h @@ -184,6 +184,15 @@ class Import advance(size_t skip) { this->stream_->advance(skip); } + // Skip a semicolon if using an older version. + void + require_semicolon_if_old_version() + { + if (this->version_ == EXPORT_FORMAT_V1 + || this->version_ == EXPORT_FORMAT_V2) + this->require_c_string(";"); + } + // Read an identifier. std::string read_identifier(); diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 3768719a03a..573011a2565 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -10892,7 +10892,7 @@ Named_type::export_named_type(Export* exp, const std::string&) const // be written by Export::write_type anyhow. exp->write_c_string("type "); exp->write_type(this); - exp->write_c_string(";\n"); + exp->write_c_string("\n"); } // Import a named type. @@ -10904,7 +10904,8 @@ Named_type::import_named_type(Import* imp, Named_type** ptype) Type *type = imp->read_type(); *ptype = type->named_type(); go_assert(*ptype != NULL); - imp->require_c_string(";\n"); + imp->require_semicolon_if_old_version(); + imp->require_c_string("\n"); } // Export the type when it is referenced by another type. In this diff --git a/libgo/go/go/internal/gccgoimporter/importer.go b/libgo/go/go/internal/gccgoimporter/importer.go index 7bc2afc4d78..d3ce10cb0ca 100644 --- a/libgo/go/go/internal/gccgoimporter/importer.go +++ b/libgo/go/go/internal/gccgoimporter/importer.go @@ -64,6 +64,7 @@ func findExportFile(searchpaths []string, pkgpath string) (string, error) { const ( gccgov1Magic = "v1;\n" gccgov2Magic = "v2;\n" + gccgov3Magic = "v3;\n" goimporterMagic = "\n$$ " archiveMagic = "!>", want: "*error"}, {id: "foo", typ: "", want: "unsafe.Pointer"}, {id: "foo", typ: ">>", want: "foo.Bar", underlying: "*foo.Bar"}, - {id: "foo", typ: " func (? ) M (); >", want: "bar.Foo", underlying: "int8", methods: "func (bar.Foo).M()"}, + {id: "foo", typ: "\n func (? ) M ()\n>", want: "bar.Foo", underlying: "int8", methods: "func (bar.Foo).M()"}, {id: "foo", typ: ">", want: "bar.foo", underlying: "int8"}, {id: "foo", typ: ">", want: "[]int8"}, {id: "foo", typ: ">", want: "[42]int8"},