Commit b4d216f6 by Ian Lance Taylor

compiler: Add pkgpath symbol information to export data.

This adds the pkgpath symbol to the export data whenever it is
needed--whenever the pkgpath symbol is not the obvious
transformation of the pkgpath.  This lets us determine the
correct symbol name for indirectly imported packages compiled
with -fgo-prefix.

From-SVN: r220291
parent 622599c6
......@@ -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
......
......@@ -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);
......
......@@ -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_;
}
......
......@@ -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
......
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment