// Now that we know the name of the package we are compiling, set
// the package path to use for reflect.Type.PkgPath and global
// symbol names.
- if (!this->pkgpath_set_)
+ if (this->pkgpath_set_)
+ this->pkgpath_symbol_ = Gogo::pkgpath_for_symbol(this->pkgpath_);
+ else
{
if (!this->prefix_from_option_ && package_name == "main")
- this->pkgpath_ = package_name;
+ {
+ this->pkgpath_ = package_name;
+ this->pkgpath_symbol_ = Gogo::pkgpath_for_symbol(package_name);
+ }
else
{
if (!this->prefix_from_option_)
this->prefix_ = "go";
this->pkgpath_ = this->prefix_ + '.' + package_name;
+ this->pkgpath_symbol_ = (Gogo::pkgpath_for_symbol(this->prefix_) + '.'
+ + Gogo::pkgpath_for_symbol(package_name));
}
this->pkgpath_set_ = true;
}
- this->pkgpath_symbol_ = Gogo::pkgpath_for_symbol(this->pkgpath_);
-
- this->package_ = this->register_package(this->pkgpath_, location);
+ this->package_ = this->register_package(this->pkgpath_,
+ this->pkgpath_symbol_, location);
this->package_->set_package_name(package_name, location);
if (this->is_main_package())
const std::string& alias_arg,
bool is_alias_exported,
const std::string& pkgpath,
+ const std::string& pkgpath_symbol,
Location location,
bool* padd_to_globals)
{
- Package* ret = this->register_package(pkgpath, location);
+ Package* ret = this->register_package(pkgpath, pkgpath_symbol, location);
ret->set_package_name(real_name, location);
*padd_to_globals = false;
// Register a package. This package may or may not be imported. This
// returns the Package structure for the package, creating if it
// necessary. LOCATION is the location of the import statement that
-// led us to see this package.
+// led us to see this package. PKGPATH_SYMBOL is the symbol to use
+// for names in the package; it may be the empty string, in which case
+// we either get it later or make a guess when we need it.
Package*
-Gogo::register_package(const std::string& pkgpath, Location location)
+Gogo::register_package(const std::string& pkgpath,
+ const std::string& pkgpath_symbol, Location location)
{
Package* package = NULL;
std::pair<Packages::iterator, bool> ins =
// We have seen this package name before.
package = ins.first->second;
go_assert(package != NULL && package->pkgpath() == pkgpath);
+ if (!pkgpath_symbol.empty())
+ package->set_pkgpath_symbol(pkgpath_symbol);
if (Linemap::is_unknown_location(package->location()))
package->set_location(location);
}
else
{
// First time we have seen this package name.
- package = new Package(pkgpath, location);
+ package = new Package(pkgpath, pkgpath_symbol, location);
go_assert(ins.first->second == NULL);
ins.first->second = package;
}
// support streaming to a separate file.
Stream_to_section stream;
+ // Write out either the prefix or pkgpath depending on how we were
+ // invoked.
+ std::string prefix;
+ std::string pkgpath;
+ if (this->pkgpath_from_option_)
+ pkgpath = this->pkgpath_;
+ else if (this->prefix_from_option_)
+ prefix = this->prefix_;
+ else if (this->is_main_package())
+ pkgpath = "main";
+ else
+ prefix = "go";
+
Export exp(&stream);
exp.register_builtin_types(this);
exp.export_globals(this->package_name(),
- this->pkgpath(),
+ prefix,
+ pkgpath,
this->package_priority(),
this->imports_,
(this->need_init_fn_ && !this->is_main_package()
// Class Package.
-Package::Package(const std::string& pkgpath, Location location)
- : pkgpath_(pkgpath), pkgpath_symbol_(Gogo::pkgpath_for_symbol(pkgpath)),
+Package::Package(const std::string& pkgpath,
+ const std::string& pkgpath_symbol, Location location)
+ : pkgpath_(pkgpath), pkgpath_symbol_(pkgpath_symbol),
package_name_(), bindings_(new Bindings(NULL)), priority_(0),
location_(location), used_(false), is_imported_(false),
uses_sink_alias_(false)
package_name.c_str());
}
+// Return the pkgpath symbol, which is a prefix for symbols defined in
+// this package.
+
+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 this->pkgpath_symbol_;
+}
+
+// Set the package path symbol.
+
+void
+Package::set_pkgpath_symbol(const std::string& pkgpath_symbol)
+{
+ go_assert(!pkgpath_symbol.empty());
+ if (this->pkgpath_symbol_.empty())
+ this->pkgpath_symbol_ = pkgpath_symbol;
+ else
+ go_assert(this->pkgpath_symbol_ == pkgpath_symbol);
+}
+
// Set the priority. We may see multiple priorities for an imported
// package; we want to use the largest one.
add_imported_package(const std::string& real_name, const std::string& alias,
bool is_alias_exported,
const std::string& pkgpath,
+ const std::string& pkgpath_symbol,
Location location,
bool* padd_to_globals);
// This returns the Package structure for the package, creating if
// it necessary.
Package*
- register_package(const std::string& pkgpath, Location);
+ register_package(const std::string& pkgpath,
+ const std::string& pkgpath_symbol, Location);
// Start compiling a function. ADD_METHOD_TO_TYPE is true if a
// method function should be added to the type of its receiver.
class Package
{
public:
- Package(const std::string& pkgpath, Location location);
+ Package(const std::string& pkgpath, const std::string& pkgpath_symbol,
+ Location location);
// Get the package path used for all symbols exported from this
// package.
{ return this->pkgpath_; }
// Return the package path to use for a symbol name.
- const std::string&
- pkgpath_symbol() const
- { return this->pkgpath_symbol_; }
+ std::string
+ pkgpath_symbol() const;
+
+ // Set the package path symbol.
+ void
+ set_pkgpath_symbol(const std::string&);
// Return the location of the import statement.
Location
this->require_c_string(";\n");
std::string pkgpath;
+ std::string pkgpath_symbol;
if (this->match_c_string("prefix "))
{
this->advance(7);
std::string unique_prefix = this->read_identifier();
this->require_c_string(";\n");
pkgpath = unique_prefix + '.' + package_name;
+ pkgpath_symbol = (Gogo::pkgpath_for_symbol(unique_prefix) + '.'
+ + Gogo::pkgpath_for_symbol(package_name));
}
else
{
this->require_c_string("pkgpath ");
pkgpath = this->read_identifier();
this->require_c_string(";\n");
+ pkgpath_symbol = Gogo::pkgpath_for_symbol(pkgpath);
}
this->package_ = gogo->add_imported_package(package_name, local_name,
is_local_name_exported,
- pkgpath,
+ pkgpath, pkgpath_symbol,
this->location_,
&this->add_to_globals_);
if (this->package_ == NULL)
stream->advance(1);
this->require_c_string("\";\n");
- Package* p = this->gogo_->register_package(pkgpath,
+ Package* p = this->gogo_->register_package(pkgpath, "",
Linemap::unknown_location());
p->set_package_name(package_name, this->location());
}
package = this->package_;
else
{
- package = this->gogo_->register_package(pkgpath,
+ package = this->gogo_->register_package(pkgpath, "",
Linemap::unknown_location());
if (!package_name.empty())
package->set_package_name(package_name, this->location());