-eaf4afbabcd91df55d31955500b6db55b07f6de5
+4b857cde45939f0e9f3cf89b9e347b6f6ebe0f8f
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
+ "__"
+ this->type_->mangled_name(gogo));
- // See whether this interface has any hidden methods.
- bool has_hidden_methods = false;
- for (Typed_identifier_list::const_iterator p = interface_methods->begin();
- p != interface_methods->end();
- ++p)
- {
- if (Gogo::is_hidden_name(p->name()))
+ // Set is_public if we are converting a named type to an interface
+ // type that is defined in the same package as the named type, and
+ // the interface has hidden methods. In that case the interface
+ // method table will be defined by the package that defines the
+ // types.
+ bool is_public = false;
+ if (this->type_->named_type() != NULL
+ && (this->type_->named_type()->named_object()->package()
+ == this->itype_->package()))
+ {
+ for (Typed_identifier_list::const_iterator p = interface_methods->begin();
+ p != interface_methods->end();
+ ++p)
{
- has_hidden_methods = true;
- break;
+ if (Gogo::is_hidden_name(p->name()))
+ {
+ is_public = true;
+ break;
+ }
}
}
- // We already know that the named type is convertible to the
- // interface. If the interface has hidden methods, and the named
- // type is defined in a different package, then the interface
- // conversion table will be defined by that other package.
- if (has_hidden_methods
- && this->type_->named_type() != NULL
+ if (is_public
&& this->type_->named_type()->named_object()->package() != NULL)
{
+ // The interface conversion table is defined elsewhere.
Btype* btype = this->type()->get_backend(gogo);
std::string asm_name(go_selectively_encode_id(mangled_name));
this->bvar_ =
Bexpression* ctor =
gogo->backend()->constructor_expression(btype, ctor_bexprs, loc);
- bool is_public = has_hidden_methods && this->type_->named_type() != NULL;
std::string asm_name(go_selectively_encode_id(mangled_name));
this->bvar_ = gogo->backend()->immutable_struct(mangled_name, asm_name, false,
!is_public, btype, loc);
return package;
}
+// Return the pkgpath symbol for a package, given the pkgpath.
+
+std::string
+Gogo::pkgpath_symbol_for_package(const std::string& pkgpath)
+{
+ Packages::iterator p = this->packages_.find(pkgpath);
+ go_assert(p != this->packages_.end());
+ return p->second->pkgpath_symbol();
+}
+
// Start compiling a function.
Named_object*
// use the pkgpath of the imported package to avoid
// a possible name collision. See bug478 for a test
// case.
- pkgpath = Gogo::hidden_name_pkgpath(no->name());
- pkgpath = Gogo::pkgpath_for_symbol(pkgpath);
+ std::string p = Gogo::hidden_name_pkgpath(no->name());
+ pkgpath = gogo->pkgpath_symbol_for_package(p);
}
asm_name = pkgpath;
if (this->asm_name_.empty())
{
asm_name = (no->package() == NULL
- ? gogo->pkgpath_symbol()
- : no->package()->pkgpath_symbol());
+ ? gogo->pkgpath_symbol()
+ : no->package()->pkgpath_symbol());
+ if (this->fntype_->is_method()
+ && Gogo::is_hidden_name(no->name())
+ && Gogo::hidden_name_pkgpath(no->name()) != gogo->pkgpath())
+ {
+ // This is a method created for an unexported method of
+ // an imported embedded type. Use the pkgpath of the
+ // imported package. This matches code in
+ // Function::get_or_make_decl, above.
+ std::string p = Gogo::hidden_name_pkgpath(no->name());
+ asm_name = gogo->pkgpath_symbol_for_package(p);
+ }
asm_name.append(1, '.');
asm_name.append(Gogo::unpack_hidden_name(no->name()));
if (this->fntype_->is_method())
register_package(const std::string& pkgpath,
const std::string& pkgpath_symbol, Location);
+ // Look up a package by pkgpath, and return its pkgpath_symbol.
+ std::string
+ pkgpath_symbol_for_package(const std::string&);
+
// Start compiling a function. ADD_METHOD_TO_TYPE is true if a
// method function should be added to the type of its receiver.
Named_object*
methods = NULL;
}
- return Type::make_interface_type(methods, imp->location());
+ Interface_type* ret = Type::make_interface_type(methods, imp->location());
+ ret->package_ = imp->package();
+ return ret;
}
// Make an interface type.
Interface_type(Typed_identifier_list* methods, Location location)
: Type(TYPE_INTERFACE),
parse_methods_(methods), all_methods_(NULL), location_(location),
- interface_btype_(NULL), bmethods_(NULL), assume_identical_(NULL),
- methods_are_finalized_(false), bmethods_is_placeholder_(false),
- seen_(false)
+ package_(NULL), interface_btype_(NULL), bmethods_(NULL),
+ assume_identical_(NULL), methods_are_finalized_(false),
+ bmethods_is_placeholder_(false), seen_(false)
{ go_assert(methods == NULL || !methods->empty()); }
// The location where the interface type was defined.
location() const
{ return this->location_; }
+ // The package where the interface type was defined. Returns NULL
+ // for the package currently being compiled.
+ Package*
+ package() const
+ { return this->package_; }
+
// Return whether this is an empty interface.
bool
is_empty() const
Typed_identifier_list* all_methods_;
// The location where the interface was defined.
Location location_;
+ // The package where the interface was defined. This is NULL for
+ // the package being compiled.
+ Package* package_;
// The backend representation of this type during backend conversion.
Btype* interface_btype_;
// The backend representation of the pointer to the method table.