is_main_package() const;
// If necessary, adjust the name to use for a hidden symbol. We add
- // a prefix of the package name, so that hidden symbols in different
- // packages do not collide.
+ // the package name, so that hidden symbols in different packages do
+ // not collide.
std::string
pack_hidden_name(const std::string& name, bool is_exported) const
{
return (is_exported
? name
- : ('.' + this->unique_prefix()
- + '.' + this->package_name()
- + '.' + name));
+ : '.' + this->pkgpath() + '.' + name);
}
// Unpack a name which may have been hidden. Returns the
is_hidden_name(const std::string& name)
{ return name[0] == '.'; }
- // Return the package prefix of a hidden name.
+ // Return the package path of a hidden name.
static std::string
- hidden_name_prefix(const std::string& name)
+ hidden_name_pkgpath(const std::string& name)
{
go_assert(Gogo::is_hidden_name(name));
return name.substr(1, name.rfind('.') - 1);
&& name[name.length() - 2] == '.');
}
- // Return the unique prefix to use for all exported symbols.
+ // Convert a pkgpath into a string suitable for a symbol
+ static std::string
+ pkgpath_for_symbol(const std::string& pkgpath);
+
+ // Return the package path to use for reflect.Type.PkgPath.
+ const std::string&
+ pkgpath() const;
+
+ // Return the package path to use for a symbol name.
const std::string&
- unique_prefix() const;
+ pkgpath_symbol() const;
- // Set the unique prefix.
+ // Set the package path from a command line option.
void
- set_unique_prefix(const std::string&);
+ set_pkgpath(const std::string&);
+
+ // Set the prefix from a command line option.
+ void
+ set_prefix(const std::string&);
+
+ // Return whether pkgpath was set from a command line option.
+ bool
+ pkgpath_from_option() const
+ { return this->pkgpath_from_option_; }
// Return the priority to use for the package we are compiling.
// This is two more than the largest priority of any package we
Package*
add_imported_package(const std::string& real_name, const std::string& alias,
bool is_alias_exported,
- const std::string& unique_prefix,
+ const std::string& pkgpath,
Location location,
bool* padd_to_globals);
// This returns the Package structure for the package, creating if
// it necessary.
Package*
- register_package(const std::string& name, const std::string& unique_prefix,
- Location);
+ register_package(const std::string& pkgpath, Location);
// Start compiling a function. ADD_METHOD_TO_TYPE is true if a
// method function should be added to the type of its receiver.
void
clear_file_scope();
+ // Record that VAR1 must be initialized after VAR2. This is used
+ // when VAR2 does not appear in VAR1's INIT or PREINIT.
+ void
+ record_var_depends_on(Variable* var1, Named_object* var2)
+ {
+ go_assert(this->var_deps_.find(var1) == this->var_deps_.end());
+ this->var_deps_[var1] = var2;
+ }
+
+ // Return the variable that VAR depends on, or NULL if none.
+ Named_object*
+ var_depends_on(Variable* var) const
+ {
+ Var_deps::const_iterator p = this->var_deps_.find(var);
+ return p != this->var_deps_.end() ? p->second : NULL;
+ }
+
// Queue up a type-specific function to be written out. This is
// used when a type-specific function is needed when not at the top
// level.
void
import_unsafe(const std::string&, bool is_exported, Location);
- // Add a new imported package.
- Named_object*
- add_package(const std::string& real_name, const std::string& alias,
- const std::string& unique_prefix, Location location);
-
// Return the current binding contour.
Bindings*
current_bindings();
// Type used to map package names to packages.
typedef std::map<std::string, Package*> Packages;
- // Type used to map special names in the sys package.
- typedef std::map<std::string, std::string> Sys_names;
+ // Type used to map variables to the function calls that set them.
+ // This is used for initialization dependency analysis.
+ typedef std::map<Variable*, Named_object*> Var_deps;
// Type used to queue writing a type specific function.
struct Specific_type_function
Packages packages_;
// The functions named "init", if there are any.
std::vector<Named_object*> init_functions_;
+ // A mapping from variables to the function calls that initialize
+ // them, if it is not stored in the variable's init or preinit.
+ // This is used for dependency analysis.
+ Var_deps var_deps_;
// Whether we need a magic initialization function.
bool need_init_fn_;
// The name of the magic initialization function.
std::string init_fn_name_;
// A list of import control variables for packages that we import.
std::set<Import_init> imported_init_fns_;
- // The unique prefix used for all global symbols.
- std::string unique_prefix_;
- // Whether an explicit unique prefix was set by -fgo-prefix.
- bool unique_prefix_specified_;
+ // The package path used for reflection data.
+ std::string pkgpath_;
+ // The package path to use for a symbol name.
+ std::string pkgpath_symbol_;
+ // The prefix to use for symbols, from the -fgo-prefix option.
+ std::string prefix_;
+ // Whether pkgpath_ has been set.
+ bool pkgpath_set_;
+ // Whether an explicit package path was set by -fgo-pkgpath.
+ bool pkgpath_from_option_;
+ // Whether an explicit prefix was set by -fgo-prefix.
+ bool prefix_from_option_;
// A list of types to verify.
std::vector<Type*> verify_types_;
// A list of interface types defined while parsing.
class Package
{
public:
- Package(const std::string& name, const std::string& unique_prefix,
- Location location);
+ Package(const std::string& pkgpath, Location location);
- // The real name of this package. This may be different from the
- // name in the associated Named_object if the import statement used
- // an alias.
+ // Get the package path used for all symbols exported from this
+ // package.
const std::string&
- name() const
- { return this->name_; }
+ pkgpath() const
+ { return this->pkgpath_; }
+
+ // Return the package path to use for a symbol name.
+ const std::string&
+ pkgpath_symbol() const
+ { return this->pkgpath_symbol_; }
// Return the location of the import statement.
Location
location() const
{ return this->location_; }
- // Get the unique prefix used for all symbols exported from this
- // package.
+ // Return whether we know the name of this package yet.
+ bool
+ has_package_name() const
+ { return !this->package_name_.empty(); }
+
+ // The name that this package uses in its package clause. This may
+ // be different from the name in the associated Named_object if the
+ // import statement used an alias.
const std::string&
- unique_prefix() const
+ package_name() const
{
- go_assert(!this->unique_prefix_.empty());
- return this->unique_prefix_;
+ go_assert(!this->package_name_.empty());
+ return this->package_name_;
}
// The priority of this package. The init function of packages with
lookup(const std::string& name) const
{ return this->bindings_->lookup(name); }
- // Set the location of the package. This is used if it is seen in a
- // different import before it is really imported.
+ // Set the name of the package.
+ void
+ set_package_name(const std::string& name, Location);
+
+ // Set the location of the package. This is used to record the most
+ // recent import location.
void
set_location(Location location)
{ this->location_ = location; }
determine_types();
private:
- // The real name of this package.
- std::string name_;
- // The unique prefix for all exported global symbols.
- std::string unique_prefix_;
+ // The package path for type reflection data.
+ std::string pkgpath_;
+ // The package path for symbol names.
+ std::string pkgpath_symbol_;
+ // The name that this package uses in the package clause. This may
+ // be the empty string if it is not yet known.
+ std::string package_name_;
// The names in this package.
Bindings* bindings_;
// The priority of this package. A package has a priority higher