This patch to the Go frontend changes it to list all imported packages in the export information. This is useful for tools which want to trace package dependencies. This is another incompatible change to the export information--might as well do them together. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline.
Ian
diff -r f523a8f55403 go/export.cc --- a/go/export.cc Fri Feb 17 14:33:15 2012 -0800 +++ b/go/export.cc Fri Feb 17 15:10:46 2012 -0800 @@ -93,6 +93,7 @@ Export::export_globals(const std::string& package_name, const std::string& unique_prefix, int package_priority, + const std::map<std::string, Package*>& imports, const std::string& import_init_fn, const std::set<Import_init>& imported_init_fns, const Bindings* bindings) @@ -149,6 +150,8 @@ snprintf(buf, sizeof buf, "priority %d;\n", package_priority); this->write_c_string(buf); + this->write_imports(imports); + this->write_imported_init_fns(package_name, package_priority, import_init_fn, imported_init_fns); @@ -177,7 +180,46 @@ this->stream_->write_checksum(s); } -// Write out the import control variables for this package. +// Sort imported packages. + +static bool +import_compare(const std::pair<std::string, Package*>& a, + const std::pair<std::string, Package*>& b) +{ + return a.first < b.first; +} + +// Write out the imported packages. + +void +Export::write_imports(const std::map<std::string, Package*>& imports) +{ + // Sort the imports for more consistent output. + std::vector<std::pair<std::string, Package*> > imp; + for (std::map<std::string, Package*>::const_iterator p = imports.begin(); + p != imports.end(); + ++p) + imp.push_back(std::make_pair(p->first, p->second)); + + std::sort(imp.begin(), imp.end(), import_compare); + + for (std::vector<std::pair<std::string, Package*> >::const_iterator p = + imp.begin(); + p != imp.end(); + ++p) + { + this->write_c_string("import "); + this->write_string(p->second->name()); + this->write_c_string(" "); + this->write_string(p->second->unique_prefix()); + this->write_c_string(" \""); + this->write_string(p->first); + this->write_c_string("\";\n"); + } +} + +// Write out the initialization functions which need to run for this +// package. void Export::write_imported_init_fns( @@ -189,7 +231,7 @@ if (import_init_fn.empty() && imported_init_fns.empty()) return; - this->write_c_string("import"); + this->write_c_string("init"); if (!import_init_fn.empty()) { diff -r f523a8f55403 go/export.h --- a/go/export.h Fri Feb 17 14:33:15 2012 -0800 +++ b/go/export.h Fri Feb 17 15:10:46 2012 -0800 @@ -14,6 +14,7 @@ class Import_init; class Bindings; class Type; +class Package; // Codes used for the builtin types. These are all negative to make // them easily distinct from the codes assigned by Export::write_type. @@ -126,6 +127,7 @@ export_globals(const std::string& package_name, const std::string& unique_prefix, int package_priority, + const std::map<std::string, Package*>& imports, const std::string& import_init_fn, const std::set<Import_init>& imported_init_fns, const Bindings* bindings); @@ -158,6 +160,10 @@ Export(const Export&); Export& operator=(const Export&); + // Write out the imported packages. + void + write_imports(const std::map<std::string, Package*>& imports); + // Write out the imported initialization functions. void write_imported_init_fns(const std::string& package_name, int priority, diff -r f523a8f55403 go/gogo.cc --- a/go/gogo.cc Fri Feb 17 14:33:15 2012 -0800 +++ b/go/gogo.cc Fri Feb 17 15:10:46 2012 -0800 @@ -2859,6 +2859,7 @@ exp.export_globals(this->package_name(), this->unique_prefix(), this->package_priority(), + this->imports_, (this->need_init_fn_ && !this->is_main_package() ? this->get_init_fn_name() : ""), diff -r f523a8f55403 go/import.cc --- a/go/import.cc Fri Feb 17 14:33:15 2012 -0800 +++ b/go/import.cc Fri Feb 17 15:10:46 2012 -0800 @@ -304,7 +304,10 @@ this->package_->set_priority(prio); this->require_c_string(";\n"); - if (stream->match_c_string("import ")) + while (stream->match_c_string("import")) + this->read_one_import(); + + if (stream->match_c_string("init")) this->read_import_init_fns(gogo); // Loop over all the input data for this package. @@ -344,12 +347,24 @@ return this->package_; } +// Read an import line. We don't actually care about these. + +void +Import::read_one_import() +{ + this->require_c_string("import "); + Stream* stream = this->stream_; + while (stream->peek_char() != ';') + stream->advance(1); + this->require_c_string(";\n"); +} + // Read the list of import control functions. void Import::read_import_init_fns(Gogo* gogo) { - this->require_c_string("import"); + this->require_c_string("init"); while (!this->match_c_string(";")) { this->require_c_string(" "); diff -r f523a8f55403 go/import.h --- a/go/import.h Fri Feb 17 14:33:15 2012 -0800 +++ b/go/import.h Fri Feb 17 15:10:46 2012 -0800 @@ -213,6 +213,10 @@ find_archive_export_data(const std::string& filename, int fd, Location); + // Read an import line. + void + read_one_import(); + // Read the import control functions. void read_import_init_fns(Gogo*); diff -r f523a8f55403 go/unsafe.cc --- a/go/unsafe.cc Fri Feb 17 14:33:15 2012 -0800 +++ b/go/unsafe.cc Fri Feb 17 15:10:46 2012 -0800 @@ -34,6 +34,8 @@ package->set_location(location); package->set_is_imported(); + this->imports_.insert(std::make_pair("unsafe", package)); + Bindings* bindings = package->bindings(); // The type may have already been created by an import.