mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 12:21:09 +08:00
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
This commit is contained in:
parent
1b8b126f38
commit
097b12fb97
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
const std::string&
|
||||
unique_prefix() const;
|
||||
// Convert a pkgpath into a string suitable for a symbol
|
||||
static std::string
|
||||
pkgpath_for_symbol(const std::string& pkgpath);
|
||||
|
||||
// Set the unique prefix.
|
||||
// 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&
|
||||
pkgpath_symbol() const;
|
||||
|
||||
// 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
|
||||
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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];
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user