aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/go/gofrontend/export.cc45
-rw-r--r--gcc/go/gofrontend/export.h6
-rw-r--r--gcc/go/gofrontend/gogo.cc8
-rw-r--r--gcc/go/gofrontend/import.cc22
-rw-r--r--gcc/go/gofrontend/import.h4
5 files changed, 79 insertions, 6 deletions
diff --git a/gcc/go/gofrontend/export.cc b/gcc/go/gofrontend/export.cc
index e37f034..5c0094d 100644
--- a/gcc/go/gofrontend/export.cc
+++ b/gcc/go/gofrontend/export.cc
@@ -94,6 +94,7 @@ Export::export_globals(const std::string& package_name,
const std::string& prefix,
const std::string& pkgpath,
int package_priority,
+ const std::map<std::string, Package*>& packages,
const std::map<std::string, Package*>& imports,
const std::string& import_init_fn,
const std::set<Import_init>& imported_init_fns,
@@ -160,6 +161,8 @@ Export::export_globals(const std::string& package_name,
snprintf(buf, sizeof buf, "priority %d;\n", package_priority);
this->write_c_string(buf);
+ this->write_packages(packages);
+
this->write_imports(imports);
this->write_imported_init_fns(package_name, package_priority, import_init_fn,
@@ -190,6 +193,48 @@ Export::export_globals(const std::string& package_name,
this->stream_->write_checksum(s);
}
+// Sort packages.
+
+static bool
+packages_compare(const Package* a, const Package* b)
+{
+ return a->package_name() < b->package_name();
+}
+
+// Write out all the known packages whose pkgpath symbol is not a
+// simple transformation of the pkgpath, so that the importing code
+// can reliably know it.
+
+void
+Export::write_packages(const std::map<std::string, Package*>& packages)
+{
+ // Sort for consistent output.
+ std::vector<Package*> out;
+ for (std::map<std::string, Package*>::const_iterator p = packages.begin();
+ p != packages.end();
+ ++p)
+ {
+ if (p->second->pkgpath_symbol()
+ != Gogo::pkgpath_for_symbol(p->second->pkgpath()))
+ out.push_back(p->second);
+ }
+
+ std::sort(out.begin(), out.end(), packages_compare);
+
+ for (std::vector<Package*>::const_iterator p = out.begin();
+ p != out.end();
+ ++p)
+ {
+ this->write_c_string("package ");
+ this->write_string((*p)->package_name());
+ this->write_c_string(" ");
+ this->write_string((*p)->pkgpath());
+ this->write_c_string(" ");
+ this->write_string((*p)->pkgpath_symbol());
+ this->write_c_string(";\n");
+ }
+}
+
// Sort imported packages.
static bool
diff --git a/gcc/go/gofrontend/export.h b/gcc/go/gofrontend/export.h
index c010a14..0526e9a 100644
--- a/gcc/go/gofrontend/export.h
+++ b/gcc/go/gofrontend/export.h
@@ -120,6 +120,7 @@ class Export : public String_dump
// PREFIX is the package prefix. PKGPATH is the package path.
// Only one of PREFIX and PKGPATH will be non-empty.
// PACKAGE_PRIORITY is the priority to use for this package.
+ // PACKAGES is all the packages we have seen.
// IMPORTS is the explicitly imported packages.
// IMPORT_INIT_FN is the name of the import initialization function
// for this package; it will be empty if none is needed.
@@ -130,6 +131,7 @@ class Export : public String_dump
const std::string& prefix,
const std::string& pkgpath,
int package_priority,
+ const std::map<std::string, Package*>& packages,
const std::map<std::string, Package*>& imports,
const std::string& import_init_fn,
const std::set<Import_init>& imported_init_fns,
@@ -163,6 +165,10 @@ class Export : public String_dump
Export(const Export&);
Export& operator=(const Export&);
+ // Write out all known packages.
+ void
+ write_packages(const std::map<std::string, Package*>& packages);
+
// Write out the imported packages.
void
write_imports(const std::map<std::string, Package*>& imports);
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 9039ce3..6196f03 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -4364,6 +4364,7 @@ Gogo::do_exports()
prefix,
pkgpath,
this->package_priority(),
+ this->packages_,
this->imports_,
(this->need_init_fn_ && !this->is_main_package()
? this->get_init_fn_name()
@@ -7537,12 +7538,7 @@ std::string
Package::pkgpath_symbol() const
{
if (this->pkgpath_symbol_.empty())
- {
- // In the general case, this is wrong, because the package might
- // have been compiled with -fprefix. However, it is what we
- // used to do, so it is no more wrong than we were before.
- return Gogo::pkgpath_for_symbol(this->pkgpath_);
- }
+ return Gogo::pkgpath_for_symbol(this->pkgpath_);
return this->pkgpath_symbol_;
}
diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc
index cfc0429..e1fba78 100644
--- a/gcc/go/gofrontend/import.cc
+++ b/gcc/go/gofrontend/import.cc
@@ -338,6 +338,9 @@ Import::import(Gogo* gogo, const std::string& local_name,
this->package_->set_priority(prio);
this->require_c_string(";\n");
+ while (stream->match_c_string("package"))
+ this->read_one_package();
+
while (stream->match_c_string("import"))
this->read_one_import();
@@ -381,6 +384,25 @@ Import::import(Gogo* gogo, const std::string& local_name,
return this->package_;
}
+// Read a package line. This let us reliably determine the pkgpath
+// symbol, even if the package was compiled with a -fgo-prefix option.
+
+void
+Import::read_one_package()
+{
+ this->require_c_string("package ");
+ std::string package_name = this->read_identifier();
+ this->require_c_string(" ");
+ std::string pkgpath = this->read_identifier();
+ this->require_c_string(" ");
+ std::string pkgpath_symbol = this->read_identifier();
+ this->require_c_string(";\n");
+
+ Package* p = this->gogo_->register_package(pkgpath, pkgpath_symbol,
+ Linemap::unknown_location());
+ p->set_package_name(package_name, this->location());
+}
+
// Read an import line. We don't actually care about these.
void
diff --git a/gcc/go/gofrontend/import.h b/gcc/go/gofrontend/import.h
index 9917937..2a9ac80 100644
--- a/gcc/go/gofrontend/import.h
+++ b/gcc/go/gofrontend/import.h
@@ -220,6 +220,10 @@ class Import
find_archive_export_data(const std::string& filename, int fd,
Location);
+ // Read a package line.
+ void
+ read_one_package();
+
// Read an import line.
void
read_one_import();