diff options
author | Ian Lance Taylor <iant@google.com> | 2012-05-09 21:17:23 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-05-09 21:17:23 +0000 |
commit | 097b12fb975ba045fffebc2cb1de407d3dba4bbc (patch) | |
tree | 35b68564005a08b6b179869395daba334368b0bc /gcc/go | |
parent | 1b8b126f386ffff12b02f7c9cb2a00c38996f1ea (diff) | |
download | gcc-097b12fb975ba045fffebc2cb1de407d3dba4bbc.zip gcc-097b12fb975ba045fffebc2cb1de407d3dba4bbc.tar.gz gcc-097b12fb975ba045fffebc2cb1de407d3dba4bbc.tar.bz2 |
compiler: Add -fgo-pkgpath option.
* lang.opt: Add -fgo-pkgpath.
* go-lang.c (go_pkgpath): New static variable.
(go_prefix): New static variable.
(go_langhook_init): Pass go_pkgpath and go_prefix to
go_create_gogo.
(go_langhook_handle_option): Handle -fgo-pkgpath. Change
-fgo-prefix handling to just set go_prefix.
* go-c.h (go_set_prefix): Don't declare.
(go_create_gogo): Add pkgpath and prefix to declaration.
* go-gcc.cc (Gcc_backend::global_variable): Change unique_prefix
to pkgpath. Don't include the package name in the asm name.
* gccgo.texi (Invoking gccgo): Document -fgo-pkgpath. Update the
docs for -fgo-prefix.
From-SVN: r187356
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/go/gccgo.texi | 28 | ||||
-rw-r--r-- | gcc/go/go-c.h | 4 | ||||
-rw-r--r-- | gcc/go/go-gcc.cc | 8 | ||||
-rw-r--r-- | gcc/go/go-lang.c | 13 | ||||
-rw-r--r-- | gcc/go/gofrontend/backend.h | 16 | ||||
-rw-r--r-- | gcc/go/gofrontend/export.cc | 35 | ||||
-rw-r--r-- | gcc/go/gofrontend/export.h | 6 | ||||
-rw-r--r-- | gcc/go/gofrontend/go.cc | 35 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo-tree.cc | 28 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 256 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.h | 115 | ||||
-rw-r--r-- | gcc/go/gofrontend/import.cc | 101 | ||||
-rw-r--r-- | gcc/go/gofrontend/parse.cc | 12 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 98 | ||||
-rw-r--r-- | gcc/go/gofrontend/unsafe.cc | 2 | ||||
-rw-r--r-- | gcc/go/lang.opt | 4 |
17 files changed, 457 insertions, 320 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 951d3f9..67989fdb 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,19 @@ +2012-05-09 Ian Lance Taylor <iant@google.com> + + * lang.opt: Add -fgo-pkgpath. + * go-lang.c (go_pkgpath): New static variable. + (go_prefix): New static variable. + (go_langhook_init): Pass go_pkgpath and go_prefix to + go_create_gogo. + (go_langhook_handle_option): Handle -fgo-pkgpath. Change + -fgo-prefix handling to just set go_prefix. + * go-c.h (go_set_prefix): Don't declare. + (go_create_gogo): Add pkgpath and prefix to declaration. + * go-gcc.cc (Gcc_backend::global_variable): Change unique_prefix + to pkgpath. Don't include the package name in the asm name. + * gccgo.texi (Invoking gccgo): Document -fgo-pkgpath. Update the + docs for -fgo-prefix. + 2012-04-30 Jan Hubicka <jh@suse.cz> * gogo-tree.cc (Gogo::write_globals): Use finalize_compilation_unit. diff --git a/gcc/go/gccgo.texi b/gcc/go/gccgo.texi index 5d0efb4..a5e37e7 100644 --- a/gcc/go/gccgo.texi +++ b/gcc/go/gccgo.texi @@ -157,14 +157,32 @@ compile time. When linking, specify a library search directory, as with @command{gcc}. +@item -fgo-pkgpath=@var{string} +@cindex @option{-fgo-pkgpath} +Set the package path to use. This sets the value returned by the +PkgPath method of reflect.Type objects. It is also used for the names +of globally visible symbols. The argument to this option should +normally be the string that will be used to import this package after +it has been installed; in other words, a pathname within the +directories specified by the @option{-I} option. + @item -fgo-prefix=@var{string} @cindex @option{-fgo-prefix} +An alternative to @option{-fgo-pkgpath}. The argument will be +combined with the package name from the source file to produce the +package path. If @option{-fgo-pkgpath} is used, @option{-fgo-prefix} +will be ignored. + Go permits a single program to include more than one package with the -same name. This option is required to make this work with -@command{gccgo}. The argument to this option may be any string. Each -package with the same name must use a distinct @option{-fgo-prefix} -option. The argument is typically the full path under which the -package will be installed, as that must obviously be unique. +same name in the @code{package} clause in the source file, though +obviously the two packages must be imported using different pathnames. +In order for this to work with @command{gccgo}, either +@option{-fgo-pkgpath} or @option{-fgo-prefix} must be specified when +compiling a package. + +Using either @option{-fgo-pkgpath} or @option{-fgo-prefix} disables +the special treatment of the @code{main} package and permits that +package to be imported like any other. @item -frequire-return-statement @itemx -fno-require-return-statement diff --git a/gcc/go/go-c.h b/gcc/go/go-c.h index e123d52..d46a087 100644 --- a/gcc/go/go-c.h +++ b/gcc/go/go-c.h @@ -38,11 +38,11 @@ extern "C" extern int go_enable_dump (const char*); extern int go_enable_optimize (const char*); -extern void go_set_prefix (const char*); extern void go_add_search_path (const char*); -extern void go_create_gogo (int int_type_size, int pointer_size); +extern void go_create_gogo (int int_type_size, int pointer_size, + const char* pkgpath, const char *prefix); extern void go_parse_input_files (const char**, unsigned int, bool only_check_syntax, diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 08950b8..4729a3b 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -271,7 +271,7 @@ class Gcc_backend : public Backend Bvariable* global_variable(const std::string& package_name, - const std::string& unique_prefix, + const std::string& pkgpath, const std::string& name, Btype* btype, bool is_external, @@ -1281,7 +1281,7 @@ Gcc_backend::non_zero_size_type(tree type) Bvariable* Gcc_backend::global_variable(const std::string& package_name, - const std::string& unique_prefix, + const std::string& pkgpath, const std::string& name, Btype* btype, bool is_external, @@ -1310,9 +1310,9 @@ Gcc_backend::global_variable(const std::string& package_name, { TREE_PUBLIC(decl) = 1; - std::string asm_name(unique_prefix); + std::string asm_name(pkgpath); asm_name.push_back('.'); - asm_name.append(var_name); + asm_name.append(name); SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name)); } TREE_USED(decl) = 1; diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c index 895e39d..f02f769 100644 --- a/gcc/go/go-lang.c +++ b/gcc/go/go-lang.c @@ -81,6 +81,11 @@ struct GTY(()) language_function int dummy; }; +/* Option information we need to pass to go_create_gogo. */ + +static const char *go_pkgpath = NULL; +static const char *go_prefix = NULL; + /* Language hooks. */ static bool @@ -96,7 +101,7 @@ go_langhook_init (void) to, e.g., unsigned_char_type_node) but before calling build_common_builtin_nodes (because it calls, indirectly, go_type_for_size). */ - go_create_gogo (INT_TYPE_SIZE, POINTER_SIZE); + go_create_gogo (INT_TYPE_SIZE, POINTER_SIZE, go_pkgpath, go_prefix); build_common_builtin_nodes (); @@ -227,8 +232,12 @@ go_langhook_handle_option ( ret = go_enable_optimize (arg) ? true : false; break; + case OPT_fgo_pkgpath_: + go_pkgpath = arg; + break; + case OPT_fgo_prefix_: - go_set_prefix (arg); + go_prefix = arg; break; default: diff --git a/gcc/go/gofrontend/backend.h b/gcc/go/gofrontend/backend.h index d314045..2b14132 100644 --- a/gcc/go/gofrontend/backend.h +++ b/gcc/go/gofrontend/backend.h @@ -321,16 +321,16 @@ class Backend error_variable() = 0; // Create a global variable. PACKAGE_NAME is the name of the - // package where the variable is defined. UNIQUE_PREFIX is the - // prefix for that package, from the -fgo-prefix option. NAME is - // the name of the variable. BTYPE is the type of the variable. - // IS_EXTERNAL is true if the variable is defined in some other - // package. IS_HIDDEN is true if the variable is not exported (name - // begins with a lower case letter). LOCATION is where the variable - // was defined. + // package where the variable is defined. PKGPATH is the package + // path for that package, from the -fgo-pkgpath or -fgo-prefix + // option. NAME is the name of the variable. BTYPE is the type of + // the variable. IS_EXTERNAL is true if the variable is defined in + // some other package. IS_HIDDEN is true if the variable is not + // exported (name begins with a lower case letter). LOCATION is + // where the variable was defined. virtual Bvariable* global_variable(const std::string& package_name, - const std::string& unique_prefix, + const std::string& pkgpath, const std::string& name, Btype* btype, bool is_external, diff --git a/gcc/go/gofrontend/export.cc b/gcc/go/gofrontend/export.cc index 1745967..13c61a5 100644 --- a/gcc/go/gofrontend/export.cc +++ b/gcc/go/gofrontend/export.cc @@ -33,7 +33,7 @@ const int Export::v1_checksum_len; // Constructor. Export::Export(Stream* stream) - : stream_(stream), type_refs_(), type_index_(1) + : stream_(stream), type_refs_(), type_index_(1), packages_() { } @@ -91,7 +91,7 @@ should_export(Named_object* no) void Export::export_globals(const std::string& package_name, - const std::string& unique_prefix, + const std::string& pkgpath, int package_priority, const std::map<std::string, Package*>& imports, const std::string& import_init_fn, @@ -140,9 +140,9 @@ Export::export_globals(const std::string& package_name, this->write_string(package_name); this->write_c_string(";\n"); - // The unique prefix. This prefix is used for all global symbols. - this->write_c_string("prefix "); - this->write_string(unique_prefix); + // The package path, used for all global symbols. + this->write_c_string("pkgpath "); + this->write_string(pkgpath); this->write_c_string(";\n"); // The package priority. @@ -209,12 +209,14 @@ Export::write_imports(const std::map<std::string, Package*>& imports) ++p) { this->write_c_string("import "); - this->write_string(p->second->name()); + this->write_string(p->second->package_name()); this->write_c_string(" "); - this->write_string(p->second->unique_prefix()); + this->write_string(p->second->pkgpath()); this->write_c_string(" \""); this->write_string(p->first); this->write_c_string("\";\n"); + + this->packages_.insert(p->second); } } @@ -333,7 +335,7 @@ Export::write_type(const Type* type) { // The builtin types should have been predefined. go_assert(!Linemap::is_predeclared_location(named_type->location()) - || (named_type->named_object()->package()->name() + || (named_type->named_object()->package()->package_name() == "unsafe")); named_object = named_type->named_object(); } @@ -345,15 +347,26 @@ Export::write_type(const Type* type) std::string s = "\""; if (package != NULL && !Gogo::is_hidden_name(named_object->name())) { - s += package->unique_prefix(); - s += '.'; - s += package->name(); + s += package->pkgpath(); s += '.'; } s += named_object->name(); s += "\" "; this->write_string(s); + // It is possible that this type was imported indirectly, and is + // not in a package in the import list. If we have not + // mentioned this package before, write out the package name + // here so that any package importing this one will know it. + if (package != NULL + && this->packages_.find(package) == this->packages_.end()) + { + this->write_c_string("\""); + this->write_string(package->package_name()); + this->packages_.insert(package); + this->write_c_string("\" "); + } + // We must add a named type to the table now, since the // definition of the type may refer to the named type via a // pointer. diff --git a/gcc/go/gofrontend/export.h b/gcc/go/gofrontend/export.h index 0e03f48..c6a4810 100644 --- a/gcc/go/gofrontend/export.h +++ b/gcc/go/gofrontend/export.h @@ -117,7 +117,7 @@ class Export : public String_dump // Export the identifiers in BINDINGS which are marked for export. // The exporting is done via a series of calls to THIS->STREAM_. If // is nothing to export, this->stream_->write will not be called. - // UNIQUE_PREFIX is a prefix for all global symbols. + // PKGPATH is the package path. // PACKAGE_PRIORITY is the priority to use for this package. // IMPORT_INIT_FN is the name of the import initialization function // for this package; it will be empty if none is needed. @@ -125,7 +125,7 @@ class Export : public String_dump // imported packages. void export_globals(const std::string& package_name, - const std::string& unique_prefix, + const std::string& pkgpath, int package_priority, const std::map<std::string, Package*>& imports, const std::string& import_init_fn, @@ -182,6 +182,8 @@ class Export : public String_dump Type_refs type_refs_; // Index number of next type. int type_index_; + // Packages we have written out. + Unordered_set(const Package*) packages_; }; // An export streamer which puts the export stream in a named section. diff --git a/gcc/go/gofrontend/go.cc b/gcc/go/gofrontend/go.cc index bfa3afd..1f2ce8a 100644 --- a/gcc/go/gofrontend/go.cc +++ b/gcc/go/gofrontend/go.cc @@ -13,11 +13,6 @@ #include "backend.h" #include "gogo.h" -// The unique prefix to use for exported symbols. This is set during -// option processing. - -static std::string unique_prefix; - // The data structures we build to represent the file. static Gogo* gogo; @@ -25,38 +20,22 @@ static Gogo* gogo; GO_EXTERN_C void -go_create_gogo(int int_type_size, int pointer_size) +go_create_gogo(int int_type_size, int pointer_size, const char *pkgpath, + const char *prefix) { go_assert(::gogo == NULL); Linemap* linemap = go_get_linemap(); ::gogo = new Gogo(go_get_backend(), linemap, int_type_size, pointer_size); - if (!unique_prefix.empty()) - ::gogo->set_unique_prefix(unique_prefix); + + if (pkgpath != NULL) + ::gogo->set_pkgpath(pkgpath); + else if (prefix != NULL) + ::gogo->set_prefix(prefix); // FIXME: This should be in the gcc dependent code. ::gogo->define_builtin_function_trees(); } -// Set the unique prefix we use for exported symbols. - -GO_EXTERN_C -void -go_set_prefix(const char* arg) -{ - unique_prefix = arg; - for (size_t i = 0; i < unique_prefix.length(); ++i) - { - char c = unique_prefix[i]; - if ((c >= 'a' && c <= 'z') - || (c >= 'A' && c <= 'Z') - || (c >= '0' && c <= '9') - || c == '_') - ; - else - unique_prefix[i] = '_'; - } -} - // Parse the input files. GO_EXTERN_C diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc index 9dea885..5f74de5 100644 --- a/gcc/go/gofrontend/gogo-tree.cc +++ b/gcc/go/gofrontend/gogo-tree.cc @@ -260,9 +260,7 @@ Gogo::get_init_fn_name() } else { - std::string s = this->unique_prefix(); - s.append(1, '.'); - s.append(this->package_name()); + std::string s = this->pkgpath_symbol(); s.append("..import"); this->init_fn_name_ = s; } @@ -984,7 +982,7 @@ Named_object::get_id(Gogo* gogo) if (this->package_ == NULL) package_name = gogo->package_name(); else - package_name = this->package_->name(); + package_name = this->package_->package_name(); decl_name = package_name + '.' + Gogo::unpack_hidden_name(this->name_); @@ -1277,9 +1275,15 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no, tree id) || this->type_->is_method()) { TREE_PUBLIC(decl) = 1; - std::string asm_name = gogo->unique_prefix(); + std::string asm_name = gogo->pkgpath_symbol(); asm_name.append(1, '.'); - asm_name.append(IDENTIFIER_POINTER(id), IDENTIFIER_LENGTH(id)); + asm_name.append(Gogo::unpack_hidden_name(no->name())); + if (this->type_->is_method()) + { + asm_name.append(1, '.'); + Type* rtype = this->type_->receiver()->type(); + asm_name.append(rtype->mangled_name(gogo)); + } SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name)); } @@ -1382,10 +1386,16 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no, tree id) if (this->asm_name_.empty()) { std::string asm_name = (no->package() == NULL - ? gogo->unique_prefix() - : no->package()->unique_prefix()); + ? gogo->pkgpath_symbol() + : no->package()->pkgpath_symbol()); asm_name.append(1, '.'); - asm_name.append(IDENTIFIER_POINTER(id), IDENTIFIER_LENGTH(id)); + asm_name.append(Gogo::unpack_hidden_name(no->name())); + if (this->fntype_->is_method()) + { + asm_name.append(1, '.'); + Type* rtype = this->fntype_->receiver()->type(); + asm_name.append(rtype->mangled_name(gogo)); + } SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name)); } diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index f9982cc..80ffe24 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -36,8 +36,12 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int int_type_size, need_init_fn_(false), init_fn_name_(), imported_init_fns_(), - unique_prefix_(), - unique_prefix_specified_(false), + pkgpath_(), + pkgpath_symbol_(), + prefix_(), + pkgpath_set_(false), + pkgpath_from_option_(false), + prefix_from_option_(false), verify_types_(), interface_types_(), specific_type_functions_(), @@ -233,6 +237,72 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int int_type_size, this->globals_->add_function_declaration("delete", NULL, delete_type, loc); } +// Convert a pkgpath into a string suitable for a symbol. Note that +// this transformation is convenient but imperfect. A -fgo-pkgpath +// option of a/b_c will conflict with a -fgo-pkgpath option of a_b/c, +// possibly leading to link time errors. + +std::string +Gogo::pkgpath_for_symbol(const std::string& pkgpath) +{ + std::string s = pkgpath; + for (size_t i = 0; i < s.length(); ++i) + { + char c = s[i]; + if ((c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || (c >= '0' && c <= '9') + || c == '_' + || c == '.' + || c == '$') + ; + else + s[i] = '_'; + } + return s; +} + +// Get the package path to use for type reflection data. This should +// ideally be unique across the entire link. + +const std::string& +Gogo::pkgpath() const +{ + go_assert(this->pkgpath_set_); + return this->pkgpath_; +} + +// Set the package path from the -fgo-pkgpath command line option. + +void +Gogo::set_pkgpath(const std::string& arg) +{ + go_assert(!this->pkgpath_set_); + this->pkgpath_ = arg; + this->pkgpath_set_ = true; + this->pkgpath_from_option_ = true; +} + +// Get the package path to use for symbol names. + +const std::string& +Gogo::pkgpath_symbol() const +{ + go_assert(this->pkgpath_set_); + return this->pkgpath_symbol_; +} + +// Set the unique prefix to use to determine the package path, from +// the -fgo-prefix command line option. + +void +Gogo::set_prefix(const std::string& arg) +{ + go_assert(!this->prefix_from_option_); + this->prefix_ = arg; + this->prefix_from_option_ = true; +} + // Munge name for use in an error message. std::string @@ -247,7 +317,7 @@ const std::string& Gogo::package_name() const { go_assert(this->package_ != NULL); - return this->package_->name(); + return this->package_->package_name(); } // Set the package name. @@ -256,24 +326,29 @@ void Gogo::set_package_name(const std::string& package_name, Location location) { - if (this->package_ != NULL && this->package_->name() != package_name) + if (this->package_ != NULL) { - error_at(location, "expected package %<%s%>", - Gogo::message_name(this->package_->name()).c_str()); + if (this->package_->package_name() != package_name) + error_at(location, "expected package %<%s%>", + Gogo::message_name(this->package_->package_name()).c_str()); return; } - // If the user did not specify a unique prefix, we always use "go". - // This in effect requires that the package name be unique. - if (this->unique_prefix_.empty()) - this->unique_prefix_ = "go"; + // 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->prefix_from_option_) + this->prefix_ = "go"; + this->pkgpath_ = this->prefix_ + '.' + package_name; + this->pkgpath_set_ = true; + } - this->package_ = this->register_package(package_name, this->unique_prefix_, - location); + this->pkgpath_symbol_ = Gogo::pkgpath_for_symbol(this->pkgpath_); - // We used to permit people to qualify symbols with the current - // package name (e.g., P.x), but we no longer do. - // this->globals_->add_package(package_name, this->package_); + this->package_ = this->register_package(this->pkgpath_, location); + this->package_->set_package_name(package_name, location); if (this->is_main_package()) { @@ -287,12 +362,14 @@ Gogo::set_package_name(const std::string& package_name, } // Return whether this is the "main" package. This is not true if -// -fgo-prefix was used. +// -fgo-pkgpath or -fgo-prefix was used. bool Gogo::is_main_package() const { - return this->package_name() == "main" && !this->unique_prefix_specified_; + return (this->package_name() == "main" + && !this->pkgpath_from_option_ + && !this->prefix_from_option_); } // Import a package. @@ -319,7 +396,8 @@ Gogo::import_package(const std::string& filename, bool is_ln_exported = is_local_name_exported; if (ln.empty()) { - ln = package->name(); + ln = package->package_name(); + go_assert(!ln.empty()); is_ln_exported = Lex::is_exported_name(ln); } if (ln == ".") @@ -353,11 +431,10 @@ Gogo::import_package(const std::string& filename, Package* package = imp.import(this, local_name, is_local_name_exported); if (package != NULL) { - if (package->name() == this->package_name() - && package->unique_prefix() == this->unique_prefix()) + if (package->pkgpath() == this->pkgpath()) error_at(location, - ("imported package uses same package name and prefix " - "as package being compiled (see -fgo-prefix option)")); + ("imported package uses same package path as package " + "being compiled (see -fgo-pkgpath option)")); this->imports_.insert(std::make_pair(filename, package)); package->set_is_imported(); @@ -510,38 +587,21 @@ Package* Gogo::add_imported_package(const std::string& real_name, const std::string& alias_arg, bool is_alias_exported, - const std::string& unique_prefix, + const std::string& pkgpath, Location location, bool* padd_to_globals) { - // FIXME: Now that we compile packages as a whole, should we permit - // importing the current package? - if (this->package_name() == real_name - && this->unique_prefix() == unique_prefix) - { - *padd_to_globals = false; - if (!alias_arg.empty() && alias_arg != ".") - { - std::string alias = this->pack_hidden_name(alias_arg, - is_alias_exported); - this->package_->bindings()->add_package(alias, this->package_); - } - return this->package_; - } - else if (alias_arg == ".") - { - *padd_to_globals = true; - return this->register_package(real_name, unique_prefix, location); - } + Package* ret = this->register_package(pkgpath, location); + ret->set_package_name(real_name, location); + + *padd_to_globals = false; + + if (alias_arg == ".") + *padd_to_globals = true; else if (alias_arg == "_") - { - Package* ret = this->register_package(real_name, unique_prefix, location); - ret->set_uses_sink_alias(); - return ret; - } + ret->set_uses_sink_alias(); else { - *padd_to_globals = false; std::string alias = alias_arg; if (alias.empty()) { @@ -549,57 +609,37 @@ Gogo::add_imported_package(const std::string& real_name, is_alias_exported = Lex::is_exported_name(alias); } alias = this->pack_hidden_name(alias, is_alias_exported); - Named_object* no = this->add_package(real_name, alias, unique_prefix, - location); + Named_object* no = this->package_->bindings()->add_package(alias, ret); if (!no->is_package()) return NULL; - return no->package_value(); } -} -// Add a package. - -Named_object* -Gogo::add_package(const std::string& real_name, const std::string& alias, - const std::string& unique_prefix, Location location) -{ - go_assert(this->in_global_scope()); - - // Register the package. Note that we might have already seen it in - // an earlier import. - Package* package = this->register_package(real_name, unique_prefix, location); - - return this->package_->bindings()->add_package(alias, package); + return ret; } // Register a package. This package may or may not be imported. This // returns the Package structure for the package, creating if it -// necessary. +// necessary. LOCATION is the location of the import statement that +// led us to see this package. Package* -Gogo::register_package(const std::string& package_name, - const std::string& unique_prefix, - Location location) +Gogo::register_package(const std::string& pkgpath, Location location) { - go_assert(!unique_prefix.empty() && !package_name.empty()); - std::string name = unique_prefix + '.' + package_name; Package* package = NULL; std::pair<Packages::iterator, bool> ins = - this->packages_.insert(std::make_pair(name, package)); + this->packages_.insert(std::make_pair(pkgpath, package)); if (!ins.second) { // We have seen this package name before. package = ins.first->second; - go_assert(package != NULL); - go_assert(package->name() == package_name - && package->unique_prefix() == unique_prefix); + go_assert(package != NULL && package->pkgpath() == pkgpath); if (Linemap::is_unknown_location(package->location())) package->set_location(location); } else { // First time we have seen this package name. - package = new Package(package_name, unique_prefix, location); + package = new Package(pkgpath, location); go_assert(ins.first->second == NULL); ins.first->second = package; } @@ -1151,7 +1191,7 @@ Gogo::clear_file_scope() && !package->uses_sink_alias() && !saw_errors()) error_at(package->location(), "imported and not used: %s", - Gogo::message_name(package->name()).c_str()); + Gogo::message_name(package->package_name()).c_str()); package->clear_is_imported(); package->clear_uses_sink_alias(); package->clear_used(); @@ -2822,27 +2862,6 @@ Gogo::check_return_statements() this->traverse(&traverse); } -// Get the unique prefix to use before all exported symbols. This -// must be unique across the entire link. - -const std::string& -Gogo::unique_prefix() const -{ - go_assert(!this->unique_prefix_.empty()); - return this->unique_prefix_; -} - -// Set the unique prefix to use before all exported symbols. This -// comes from the command line option -fgo-prefix=XXX. - -void -Gogo::set_unique_prefix(const std::string& arg) -{ - go_assert(this->unique_prefix_.empty()); - this->unique_prefix_ = arg; - this->unique_prefix_specified_ = true; -} - // Work out the package priority. It is one more than the maximum // priority of an imported package. @@ -2870,7 +2889,7 @@ Gogo::do_exports() Export exp(&stream); exp.register_builtin_types(this); exp.export_globals(this->package_name(), - this->unique_prefix(), + this->pkgpath(), this->package_priority(), this->imports_, (this->need_init_fn_ && !this->is_main_package() @@ -4199,10 +4218,10 @@ Variable::get_backend_variable(Gogo* gogo, Named_object* function, if (this->is_global_) bvar = backend->global_variable((package == NULL ? gogo->package_name() - : package->name()), + : package->package_name()), (package == NULL - ? gogo->unique_prefix() - : package->unique_prefix()), + ? gogo->pkgpath_symbol() + : package->pkgpath_symbol()), n, btype, package != NULL, @@ -4556,7 +4575,12 @@ Named_object::message_name() const { if (this->package_ == NULL) return Gogo::message_name(this->name_); - std::string ret = Gogo::message_name(this->package_->name()); + std::string ret; + if (this->package_->has_package_name()) + ret = this->package_->package_name(); + else + ret = this->package_->pkgpath(); + ret = Gogo::message_name(ret); ret += '.'; ret += Gogo::message_name(this->name_); return ret; @@ -5213,13 +5237,29 @@ Unnamed_label::get_goto(Translate_context* context, Location location) // Class Package. -Package::Package(const std::string& name, const std::string& unique_prefix, - Location location) - : name_(name), unique_prefix_(unique_prefix), bindings_(new Bindings(NULL)), - priority_(0), location_(location), used_(false), is_imported_(false), +Package::Package(const std::string& pkgpath, Location location) + : pkgpath_(pkgpath), pkgpath_symbol_(Gogo::pkgpath_for_symbol(pkgpath)), + package_name_(), bindings_(new Bindings(NULL)), priority_(0), + location_(location), used_(false), is_imported_(false), uses_sink_alias_(false) { - go_assert(!name.empty() && !unique_prefix.empty()); + go_assert(!pkgpath.empty()); + +} + +// Set the package name. + +void +Package::set_package_name(const std::string& package_name, Location location) +{ + go_assert(!package_name.empty()); + if (this->package_name_.empty()) + this->package_name_ = package_name; + else if (this->package_name_ != package_name) + error_at(location, + "saw two different packages with the same package path %s: %s, %s", + this->pkgpath_.c_str(), this->package_name_.c_str(), + package_name.c_str()); } // Set the priority. We may see multiple priorities for an imported diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 4990bf2..deb9968 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -138,16 +138,14 @@ class Gogo 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 @@ -161,9 +159,9 @@ class Gogo 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); @@ -183,13 +181,30 @@ class Gogo && 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 package path from a command line option. + void + set_pkgpath(const std::string&); - // Set the unique prefix. + // Set the prefix from a command line option. void - set_unique_prefix(const std::string&); + 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 @@ -229,7 +244,7 @@ class Gogo 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); @@ -237,8 +252,7 @@ class Gogo // 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. @@ -609,11 +623,6 @@ class Gogo 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(); @@ -711,10 +720,18 @@ class Gogo 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. @@ -2409,28 +2426,37 @@ class Unnamed_label 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 @@ -2500,8 +2526,12 @@ class Package 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; } @@ -2537,10 +2567,13 @@ class Package 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 diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc index b0d1008..9febf23 100644 --- a/gcc/go/gofrontend/import.cc +++ b/gcc/go/gofrontend/import.cc @@ -281,13 +281,24 @@ Import::import(Gogo* gogo, const std::string& local_name, std::string package_name = this->read_identifier(); this->require_c_string(";\n"); - this->require_c_string("prefix "); - std::string unique_prefix = this->read_identifier(); - this->require_c_string(";\n"); + std::string pkgpath; + 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; + } + else + { + this->require_c_string("pkgpath "); + pkgpath = this->read_identifier(); + this->require_c_string(";\n"); + } this->package_ = gogo->add_imported_package(package_name, local_name, is_local_name_exported, - unique_prefix, + pkgpath, this->location_, &this->add_to_globals_); if (this->package_ == NULL) @@ -353,10 +364,18 @@ void Import::read_one_import() { this->require_c_string("import "); + std::string package_name = this->read_identifier(); + this->require_c_string(" "); + std::string pkgpath = this->read_identifier(); + this->require_c_string(" \""); Stream* stream = this->stream_; - while (stream->peek_char() != ';') + while (stream->peek_char() != '"') stream->advance(1); - this->require_c_string(";\n"); + this->require_c_string("\";\n"); + + Package* p = this->gogo_->register_package(pkgpath, + Linemap::unknown_location()); + p->set_package_name(package_name, this->location()); } // Read the list of import control functions. @@ -572,55 +591,50 @@ Import::read_type() while ((c = stream->get_char()) != '"') type_name += c; - // If this type is in the current package, the name will be - // .PREFIX.PACKAGE.NAME or simply NAME with no dots. Otherwise, a - // non-hidden symbol will be PREFIX.PACKAGE.NAME and a hidden symbol - // will be .PREFIX.PACKAGE.NAME. - std::string package_name; - std::string unique_prefix; + // If this type is in the package we are currently importing, the + // name will be .PKGPATH.NAME or simply NAME with no dots. + // Otherwise, a non-hidden symbol will be PKGPATH.NAME and a hidden + // symbol will be .PKGPATH.NAME. + std::string pkgpath; if (type_name.find('.') != std::string::npos) { - bool is_hidden = false; size_t start = 0; if (type_name[0] == '.') - { - ++start; - is_hidden = true; - } - size_t dot1 = type_name.find('.', start); - size_t dot2; - if (dot1 == std::string::npos) - dot2 = std::string::npos; - else - dot2 = type_name.find('.', dot1 + 1); - if (dot1 == std::string::npos || dot2 == std::string::npos) - { - error_at(this->location_, - ("error at import data at %d: missing dot in type name"), - stream->pos()); - stream->set_saw_error(); - } - else - { - unique_prefix = type_name.substr(start, dot1 - start); - package_name = type_name.substr(dot1 + 1, dot2 - (dot1 + 1)); - } - if (!is_hidden) - type_name.erase(0, dot2 + 1); + start = 1; + size_t dot = type_name.rfind('.'); + pkgpath = type_name.substr(start, dot - start); + if (type_name[0] != '.') + type_name.erase(0, dot + 1); } this->require_c_string(" "); + // The package name may follow. This is the name of the package in + // the package clause of that package. The type name will include + // the pkgpath, which may be different. + std::string package_name; + if (stream->peek_char() == '"') + { + stream->advance(1); + while ((c = stream->get_char()) != '"') + package_name += c; + this->require_c_string(" "); + } + // Declare the type in the appropriate package. If we haven't seen // it before, mark it as invisible. We declare it before we read // the actual definition of the type, since the definition may refer // to the type itself. Package* package; - if (package_name.empty()) + if (pkgpath.empty() || pkgpath == this->gogo_->pkgpath()) package = this->package_; else - package = this->gogo_->register_package(package_name, unique_prefix, - Linemap::unknown_location()); + { + package = this->gogo_->register_package(pkgpath, + Linemap::unknown_location()); + if (!package_name.empty()) + package->set_package_name(package_name, this->location()); + } Named_object* no = package->bindings()->lookup(type_name); if (no == NULL) @@ -628,8 +642,7 @@ Import::read_type() else if (!no->is_type_declaration() && !no->is_type()) { error_at(this->location_, "imported %<%s.%s%> both type and non-type", - Gogo::message_name(package->name()).c_str(), - Gogo::message_name(type_name).c_str()); + pkgpath.c_str(), Gogo::message_name(type_name).c_str()); stream->set_saw_error(); return Type::make_error_type(); } @@ -772,9 +785,7 @@ Import::read_name() if (ret == "?") ret.clear(); else if (!Lex::is_exported_name(ret)) - ret = ('.' + this->package_->unique_prefix() - + '.' + this->package_->name() - + '.' + ret); + ret = '.' + this->package_->pkgpath() + '.' + ret; return ret; } diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index fc2c229..29323f0 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -323,13 +323,13 @@ Parse::type_name(bool issue_error) && package->name() != this->gogo_->package_name()) { // Check whether the name is there but hidden. - std::string s = ('.' + package->package_value()->unique_prefix() - + '.' + package->package_value()->name() + std::string s = ('.' + package->package_value()->pkgpath() + '.' + name); named_object = package->package_value()->lookup(s); if (named_object != NULL) { - const std::string& packname(package->package_value()->name()); + Package* p = package->package_value(); + const std::string& packname(p->package_name()); error_at(location, "invalid reference to hidden type %<%s.%s%>", Gogo::message_name(packname).c_str(), Gogo::message_name(name).c_str()); @@ -345,7 +345,7 @@ Parse::type_name(bool issue_error) named_object = this->gogo_->add_unknown_name(name, location); else { - const std::string& packname(package->package_value()->name()); + const std::string& packname(package->package_value()->package_name()); error_at(location, "reference to undefined identifier %<%s.%s%>", Gogo::message_name(packname).c_str(), Gogo::message_name(name).c_str()); @@ -2384,7 +2384,7 @@ Parse::operand(bool may_be_sink) { go_assert(package != NULL); error_at(location, "invalid reference to hidden type %<%s.%s%>", - Gogo::message_name(package->name()).c_str(), + Gogo::message_name(package->package_name()).c_str(), Gogo::message_name(id).c_str()); return Expression::make_error(location); } @@ -2394,7 +2394,7 @@ Parse::operand(bool may_be_sink) { if (package != NULL) { - std::string n1 = Gogo::message_name(package->name()); + std::string n1 = Gogo::message_name(package->package_name()); std::string n2 = Gogo::message_name(id); if (!is_exported) error_at(location, diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 74bab41..35770c7 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -1301,15 +1301,10 @@ Type::type_descriptor_var_name(Gogo* gogo, Named_type* nt) go_assert(in_function == NULL); else { - const std::string& unique_prefix(no->package() == NULL - ? gogo->unique_prefix() - : no->package()->unique_prefix()); - const std::string& package_name(no->package() == NULL - ? gogo->package_name() - : no->package()->name()); - ret.append(unique_prefix); - ret.append(1, '.'); - ret.append(package_name); + const std::string& pkgpath(no->package() == NULL + ? gogo->pkgpath_symbol() + : no->package()->pkgpath_symbol()); + ret.append(pkgpath); ret.append(1, '.'); if (in_function != NULL) { @@ -1317,7 +1312,20 @@ Type::type_descriptor_var_name(Gogo* gogo, Named_type* nt) ret.append(1, '.'); } } - ret.append(no->name()); + + // FIXME: This adds in pkgpath twice for hidden symbols, which is + // pointless. + const std::string& name(no->name()); + if (!Gogo::is_hidden_name(name)) + ret.append(name); + else + { + ret.append(1, '.'); + ret.append(Gogo::pkgpath_for_symbol(Gogo::hidden_name_pkgpath(name))); + ret.append(1, '.'); + ret.append(Gogo::unpack_hidden_name(name)); + } + return ret; } @@ -1977,15 +1985,10 @@ Type::uncommon_type_constructor(Gogo* gogo, Type* uncommon_type, else { const Package* package = no->package(); - const std::string& unique_prefix(package == NULL - ? gogo->unique_prefix() - : package->unique_prefix()); - const std::string& package_name(package == NULL - ? gogo->package_name() - : package->name()); - n.assign(unique_prefix); - n.append(1, '.'); - n.append(package_name); + const std::string& pkgpath(package == NULL + ? gogo->pkgpath() + : package->pkgpath()); + n.assign(pkgpath); if (name->in_function() != NULL) { n.append(1, '.'); @@ -2096,7 +2099,8 @@ Type::method_constructor(Gogo*, Type* method_type, vals->push_back(Expression::make_nil(bloc)); else { - s = Expression::make_string(Gogo::hidden_name_prefix(method_name), bloc); + s = Expression::make_string(Gogo::hidden_name_pkgpath(method_name), + bloc); vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc)); } @@ -4668,7 +4672,7 @@ Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name) fvals->push_back(Expression::make_nil(bloc)); else { - std::string n = Gogo::hidden_name_prefix(pf->field_name()); + std::string n = Gogo::hidden_name_pkgpath(pf->field_name()); Expression* s = Expression::make_string(n, bloc); fvals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc)); } @@ -7056,7 +7060,7 @@ Interface_type::do_type_descriptor(Gogo* gogo, Named_type* name) mvals->push_back(Expression::make_nil(bloc)); else { - s = Gogo::hidden_name_prefix(pm->name()); + s = Gogo::hidden_name_pkgpath(pm->name()); e = Expression::make_string(s, bloc); mvals->push_back(Expression::make_unary(OPERATOR_AND, e, bloc)); } @@ -7105,11 +7109,15 @@ Interface_type::do_reflection(Gogo* gogo, std::string* ret) const { if (!Gogo::is_hidden_name(p->name())) ret->append(p->name()); + else if (gogo->pkgpath_from_option()) + ret->append(p->name().substr(1)); else { - // This matches what the gc compiler does. - std::string prefix = Gogo::hidden_name_prefix(p->name()); - ret->append(prefix.substr(prefix.find('.') + 1)); + // If no -fgo-pkgpath option, backward compatibility + // for how this used to work before -fgo-pkgpath was + // introduced. + std::string pkgpath = Gogo::hidden_name_pkgpath(p->name()); + ret->append(pkgpath.substr(pkgpath.find('.') + 1)); ret->push_back('.'); ret->append(Gogo::unpack_hidden_name(p->name())); } @@ -7939,20 +7947,14 @@ Named_type::do_hash_for_method(Gogo* gogo) const // where we are going to be comparing named types for equality. In // other cases, which are cases where the runtime is going to // compare hash codes to see if the types are the same, we need to - // include the package prefix and name in the hash. + // include the pkgpath in the hash. if (gogo != NULL && !Gogo::is_hidden_name(name) && !this->is_builtin()) { const Package* package = this->named_object()->package(); if (package == NULL) - { - ret = Type::hash_string(gogo->unique_prefix(), ret); - ret = Type::hash_string(gogo->package_name(), ret); - } + ret = Type::hash_string(gogo->pkgpath(), ret); else - { - ret = Type::hash_string(package->unique_prefix(), ret); - ret = Type::hash_string(package->name(), ret); - } + ret = Type::hash_string(package->pkgpath(), ret); } return ret; @@ -8324,11 +8326,16 @@ Named_type::do_reflection(Gogo* gogo, std::string* ret) const } if (!this->is_builtin()) { + // We handle -fgo-prefix and -fgo-pkgpath differently here for + // compatibility with how the compiler worked before + // -fgo-pkgpath was introduced. const Package* package = this->named_object_->package(); - if (package != NULL) - ret->append(package->name()); + if (gogo->pkgpath_from_option()) + ret->append(package != NULL ? package->pkgpath() : gogo->pkgpath()); else - ret->append(gogo->package_name()); + ret->append(package != NULL + ? package->package_name() + : gogo->package_name()); ret->push_back('.'); } if (this->in_function_ != NULL) @@ -8355,15 +8362,10 @@ Named_type::do_mangled_name(Gogo* gogo, std::string* ret) const go_assert(this->in_function_ == NULL); else { - const std::string& unique_prefix(no->package() == NULL - ? gogo->unique_prefix() - : no->package()->unique_prefix()); - const std::string& package_name(no->package() == NULL - ? gogo->package_name() - : no->package()->name()); - name = unique_prefix; - name.append(1, '.'); - name.append(package_name); + const std::string& pkgpath(no->package() == NULL + ? gogo->pkgpath_symbol() + : no->package()->pkgpath_symbol()); + name = pkgpath; name.append(1, '.'); if (this->in_function_ != NULL) { @@ -9487,9 +9489,9 @@ Forward_declaration_type::do_mangled_name(Gogo* gogo, std::string* ret) const const Named_object* no = this->named_object(); std::string name; if (no->package() == NULL) - name = gogo->package_name(); + name = gogo->pkgpath_symbol(); else - name = no->package()->name(); + name = no->package()->pkgpath_symbol(); name += '.'; name += Gogo::unpack_hidden_name(no->name()); char buf[20]; diff --git a/gcc/go/gofrontend/unsafe.cc b/gcc/go/gofrontend/unsafe.cc index 930723e..5d0c658 100644 --- a/gcc/go/gofrontend/unsafe.cc +++ b/gcc/go/gofrontend/unsafe.cc @@ -22,7 +22,7 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported, bool add_to_globals; Package* package = this->add_imported_package("unsafe", local_name, is_local_name_exported, - "libgo_unsafe", + "libgo_unsafe.unsafe", location, &add_to_globals); if (package == NULL) diff --git a/gcc/go/lang.opt b/gcc/go/lang.opt index c14df9c..eb9ed9a 100644 --- a/gcc/go/lang.opt +++ b/gcc/go/lang.opt @@ -53,6 +53,10 @@ fgo-optimize- Go Joined RejectNegative -fgo-optimize-<type> Turn on optimization passes in the frontend +fgo-pkgpath= +Go Joined RejectNegative +-fgo-pkgpath=<string> Set Go package path + fgo-prefix= Go Joined RejectNegative -fgo-prefix=<string> Set package-specific prefix for exported Go names |