diff mbox

Go patch committed: Fix -fgo-prefix handling

Message ID CAOyqgcXvxK2A=Fp==f3pVYOH1x9FfACnkYsLiKAYcVUgFzr6Yg@mail.gmail.com
State New
Headers show

Commit Message

Ian Lance Taylor Jan. 30, 2015, 3:58 p.m. UTC
This is the followup patch.  This adds more information to the package
when any imported packages have a pkgpath symbol that is not the
obvious transformation of the pkgpath.  This is enough to determine
the right symbol name to use in all cases.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff mbox

Patch

diff -r fda36669bf1d go/export.cc
--- a/go/export.cc	Thu Jan 29 16:35:18 2015 -0800
+++ b/go/export.cc	Fri Jan 30 07:53:25 2015 -0800
@@ -94,6 +94,7 @@ 
 		       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 @@ 
   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 @@ 
   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 -r fda36669bf1d go/export.h
--- a/go/export.h	Thu Jan 29 16:35:18 2015 -0800
+++ b/go/export.h	Fri Jan 30 07:53:25 2015 -0800
@@ -120,6 +120,7 @@ 
   // 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 @@ 
 		 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 @@ 
   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 -r fda36669bf1d go/gogo.cc
--- a/go/gogo.cc	Thu Jan 29 16:35:18 2015 -0800
+++ b/go/gogo.cc	Fri Jan 30 07:53:25 2015 -0800
@@ -4364,6 +4364,7 @@ 
 		     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 @@ 
 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 -r fda36669bf1d go/import.cc
--- a/go/import.cc	Thu Jan 29 16:35:18 2015 -0800
+++ b/go/import.cc	Fri Jan 30 07:53:25 2015 -0800
@@ -338,6 +338,9 @@ 
       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 @@ 
   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 -r fda36669bf1d go/import.h
--- a/go/import.h	Thu Jan 29 16:35:18 2015 -0800
+++ b/go/import.h	Fri Jan 30 07:53:25 2015 -0800
@@ -220,6 +220,10 @@ 
   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();