X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgo%2Fgofrontend%2Ftypes.cc;h=ebf2ed9ab45a44022e82341cc58e2189189f39de;hb=daa48cceb5a55263e356e4415b409ed32dcd947f;hp=9e64a6ac84a176d5614d9ab370a3be61796c1b9a;hpb=88b6c6b482354107ba74374327825742da01eecb;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 9e64a6ac84a..ebf2ed9ab45 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -588,6 +588,9 @@ Type::are_compatible_for_comparison(bool is_equality_op, const Type *t1, p != fields->end(); ++p) { + if (Gogo::is_sink_name(p->field_name())) + continue; + if (!p->type()->is_comparable()) { if (reason != NULL) @@ -1295,29 +1298,45 @@ Type::type_descriptor_var_name(Gogo* gogo, Named_type* nt) 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; } @@ -1738,9 +1757,19 @@ Type::specific_type_functions(Gogo* gogo, Named_type* name, { // 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"; @@ -1977,19 +2006,23 @@ 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); - 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)); @@ -2096,7 +2129,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)); } @@ -4272,6 +4306,9 @@ Struct_type::do_compare_is_identity(Gogo* gogo) const pf != fields->end(); ++pf) { + if (Gogo::is_sink_name(pf->field_name())) + return false; + if (!pf->type()->compare_is_identity(gogo)) return false; @@ -4668,7 +4705,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)); } @@ -4745,6 +4782,9 @@ Struct_type::write_hash_function(Gogo* gogo, Named_type*, pf != fields->end(); ++pf) { + if (Gogo::is_sink_name(pf->field_name())) + continue; + if (first) first = false; else @@ -4836,6 +4876,9 @@ Struct_type::write_equal_function(Gogo* gogo, Named_type* name) 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); @@ -5450,6 +5493,11 @@ Array_type::get_length_tree(Gogo* gogo) 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"); @@ -6551,7 +6599,11 @@ bool 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. @@ -6802,7 +6854,8 @@ Interface_type::implements_interface(const Type* t, std::string* reason) const 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; @@ -7047,7 +7100,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)); } @@ -7096,11 +7149,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())); } @@ -7846,6 +7903,10 @@ Find_type_use::type(Type* type) 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()) @@ -7930,20 +7991,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; @@ -7962,6 +8017,11 @@ Named_type::convert(Gogo* gogo) 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. @@ -8315,17 +8375,38 @@ 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. 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())); } @@ -8346,20 +8427,22 @@ 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) { 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())); @@ -8961,7 +9044,7 @@ Type::bind_field_or_method(Gogo* gogo, const Type* type, Expression* expr, 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 " @@ -9478,9 +9561,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];