p != fields->end();
++p)
{
+ if (Gogo::is_sink_name(p->field_name()))
+ continue;
+
if (!p->type()->is_comparable())
{
if (reason != NULL)
return "__go_td_" + this->mangled_name(gogo);
Named_object* no = nt->named_object();
- const Named_object* in_function = nt->in_function();
+ unsigned int index;
+ const Named_object* in_function = nt->in_function(&index);
std::string ret = "__go_tdn_";
if (nt->is_builtin())
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)
{
ret.append(Gogo::unpack_hidden_name(in_function->name()));
ret.append(1, '.');
+ if (index > 0)
+ {
+ char buf[30];
+ snprintf(buf, sizeof buf, "%u", index);
+ ret.append(buf);
+ 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;
}
{
// This name is already hidden or not as appropriate.
base_name = name->name();
- const Named_object* in_function = name->in_function();
+ unsigned int index;
+ const Named_object* in_function = name->in_function(&index);
if (in_function != NULL)
- base_name += '$' + in_function->name();
+ {
+ base_name += '$' + Gogo::unpack_hidden_name(in_function->name());
+ if (index > 0)
+ {
+ char buf[30];
+ snprintf(buf, sizeof buf, "%u", index);
+ base_name += '$';
+ base_name += buf;
+ }
+ }
}
std::string hash_name = base_name + "$hash";
std::string equal_name = base_name + "$equal";
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);
- if (name->in_function() != NULL)
+ const std::string& pkgpath(package == NULL
+ ? gogo->pkgpath()
+ : package->pkgpath());
+ n.assign(pkgpath);
+ unsigned int index;
+ const Named_object* in_function = name->in_function(&index);
+ if (in_function != NULL)
{
n.append(1, '.');
- n.append(Gogo::unpack_hidden_name(name->in_function()->name()));
+ n.append(Gogo::unpack_hidden_name(in_function->name()));
+ if (index > 0)
+ {
+ char buf[30];
+ snprintf(buf, sizeof buf, "%u", index);
+ n.append(1, '.');
+ n.append(buf);
+ }
}
s = Expression::make_string(n, bloc);
vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
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));
}
pf != fields->end();
++pf)
{
+ if (Gogo::is_sink_name(pf->field_name()))
+ return false;
+
if (!pf->type()->compare_is_identity(gogo))
return false;
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));
}
pf != fields->end();
++pf)
{
+ if (Gogo::is_sink_name(pf->field_name()))
+ continue;
+
if (first)
first = false;
else
pf != fields->end();
++pf, ++field_index)
{
+ if (Gogo::is_sink_name(pf->field_name()))
+ continue;
+
// Compare one field in both P1 and P2.
Expression* f1 = Expression::make_temporary_reference(p1, bloc);
f1 = Expression::make_unary(OPERATOR_MULT, f1, bloc);
mpz_t val;
if (this->length_->numeric_constant_value(&nc) && nc.to_int(&val))
{
+ if (mpz_sgn(val) < 0)
+ {
+ this->length_tree_ = error_mark_node;
+ return this->length_tree_;
+ }
Type* t = nc.type();
if (t == NULL)
t = Type::lookup_integer_type("int");
Interface_type::is_identical(const Interface_type* t,
bool errors_are_identical) const
{
- go_assert(this->methods_are_finalized_ && t->methods_are_finalized_);
+ // If methods have not been finalized, then we are asking whether
+ // func redeclarations are the same. This is an error, so for
+ // simplicity we say they are never the same.
+ if (!this->methods_are_finalized_ || !t->methods_are_finalized_)
+ return false;
// We require the same methods with the same types. The methods
// have already been sorted.
std::string n = Gogo::message_name(p->name());
size_t len = 100 + n.length();
char* buf = new char[len];
- snprintf(buf, len, _("method %s%s%s requires a pointer"),
+ snprintf(buf, len,
+ _("method %s%s%s requires a pointer receiver"),
open_quote, n.c_str(), close_quote);
reason->assign(buf);
delete[] buf;
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));
}
{
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()));
}
bool
Named_type::do_verify()
{
+ if (this->is_verified_)
+ return true;
+ this->is_verified_ = true;
+
Find_type_use find(this);
Type::traverse(this->type_, &find);
if (find.found())
// 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;
this->create_placeholder(gogo);
+ // If we are called to turn unsafe.Sizeof into a constant, we may
+ // not have verified the type yet. We have to make sure it is
+ // verified, since that sets the list of dependencies.
+ this->verify();
+
// Convert all the dependencies. If they refer indirectly back to
// this type, they will pick up the intermediate tree we just
// created.
}
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. When -fgo-pkgpath is specified,
+ // we use it to make a unique reflection string, so that the
+ // type canonicalization in the reflect package will work. In
+ // order to be compatible with the gc compiler, we put tabs into
+ // the package path, so that the reflect methods can discard it.
const Package* package = this->named_object_->package();
- if (package != NULL)
- ret->append(package->name());
- else
- ret->append(gogo->package_name());
+ if (gogo->pkgpath_from_option())
+ {
+ ret->push_back('\t');
+ ret->append(package != NULL
+ ? package->pkgpath_symbol()
+ : gogo->pkgpath_symbol());
+ ret->push_back('\t');
+ }
+ ret->append(package != NULL
+ ? package->package_name()
+ : gogo->package_name());
ret->push_back('.');
}
if (this->in_function_ != NULL)
{
ret->append(Gogo::unpack_hidden_name(this->in_function_->name()));
ret->push_back('$');
+ if (this->in_function_index_ > 0)
+ {
+ char buf[30];
+ snprintf(buf, sizeof buf, "%u", this->in_function_index_);
+ ret->append(buf);
+ ret->push_back('$');
+ }
}
ret->append(Gogo::unpack_hidden_name(this->named_object_->name()));
}
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)
{
name.append(Gogo::unpack_hidden_name(this->in_function_->name()));
name.append(1, '$');
+ if (this->in_function_index_ > 0)
+ {
+ char buf[30];
+ snprintf(buf, sizeof buf, "%u", this->in_function_index_);
+ name.append(buf);
+ name.append(1, '$');
+ }
}
}
name.append(Gogo::unpack_hidden_name(no->name()));
Gogo::message_name(name).c_str(), ambig1.c_str(),
ambig2.c_str());
else if (found_pointer_method)
- error_at(location, "method requires a pointer");
+ error_at(location, "method requires a pointer receiver");
else if (nt == NULL && st == NULL && it == NULL)
error_at(location,
("reference to field %qs in object which "
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];