From f22f4fc1536bd76895feb85bb501b015f18fd452 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 2 Feb 2012 18:32:09 +0000 Subject: [PATCH] compiler: Permit importing a method to a type being defined. From-SVN: r183840 --- gcc/go/gofrontend/gogo.cc | 7 ++++--- gcc/go/gofrontend/gogo.h | 4 ++-- gcc/go/gofrontend/import.cc | 29 +++++++++++++++++++++++------ gcc/go/gofrontend/types.cc | 3 ++- gcc/go/gofrontend/types.h | 2 +- 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index c65e47f6745..fafd04fe18e 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -880,7 +880,7 @@ Gogo::declare_function(const std::string& name, Function_type* type, else if (rtype->forward_declaration_type() != NULL) { Forward_declaration_type* ftype = rtype->forward_declaration_type(); - return ftype->add_method_declaration(name, type, location); + return ftype->add_method_declaration(name, NULL, type, location); } else go_unreachable(); @@ -4325,11 +4325,12 @@ Type_declaration::add_method(const std::string& name, Function* function) Named_object* Type_declaration::add_method_declaration(const std::string& name, + Package* package, Function_type* type, Location location) { - Named_object* ret = Named_object::make_function_declaration(name, NULL, type, - location); + Named_object* ret = Named_object::make_function_declaration(name, package, + type, location); this->methods_.push_back(ret); return ret; } diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 2231e5dba5b..008c8a09872 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -1621,8 +1621,8 @@ class Type_declaration // Add a method declaration to this type. Named_object* - add_method_declaration(const std::string& name, Function_type* type, - Location location); + add_method_declaration(const std::string& name, Package*, + Function_type* type, Location location); // Return whether any methods were defined. bool diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc index de7edc91e2e..44ffda61fba 100644 --- a/gcc/go/gofrontend/import.cc +++ b/gcc/go/gofrontend/import.cc @@ -441,12 +441,29 @@ Import::import_func(Package* package) Named_object* no; if (fntype->is_method()) { - Type* rtype = receiver->type()->deref(); + Type* rtype = receiver->type(); + + // We may still be reading the definition of RTYPE, so we have + // to be careful to avoid calling base or convert. If RTYPE is + // a named type or a forward declaration, then we know that it + // is not a pointer, because we are reading a method on RTYPE + // and named pointers can't have methods. + + if (rtype->classification() == Type::TYPE_POINTER) + rtype = rtype->points_to(); + if (rtype->is_error_type()) return NULL; - Named_type* named_rtype = rtype->named_type(); - go_assert(named_rtype != NULL); - no = named_rtype->add_method_declaration(name, package, fntype, loc); + else if (rtype->named_type() != NULL) + no = rtype->named_type()->add_method_declaration(name, package, fntype, + loc); + else if (rtype->forward_declaration_type() != NULL) + no = rtype->forward_declaration_type()->add_method_declaration(name, + package, + fntype, + loc); + else + go_unreachable(); } else { @@ -647,8 +664,8 @@ Import::read_type() { // We have seen this type before. FIXME: it would be a good // idea to check that the two imported types are identical, - // but we have not finalized the methds yet, which means - // that we can nt reliably compare interface types. + // but we have not finalized the methods yet, which means + // that we can not reliably compare interface types. type = no->type_value(); // Don't change the visibility of the existing type. diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 525d33ad8e5..402039941fe 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -9115,6 +9115,7 @@ Forward_declaration_type::add_method(const std::string& name, Named_object* Forward_declaration_type::add_method_declaration(const std::string& name, + Package* package, Function_type* type, Location location) { @@ -9122,7 +9123,7 @@ Forward_declaration_type::add_method_declaration(const std::string& name, if (no->is_unknown()) no->declare_as_type(); Type_declaration* td = no->type_declaration_value(); - return td->add_method_declaration(name, type, location); + return td->add_method_declaration(name, package, type, location); } // Traversal. diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index 4e45b991b57..4398ef1e639 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -2937,7 +2937,7 @@ class Forward_declaration_type : public Type // Add a method declaration to this type. Named_object* - add_method_declaration(const std::string& name, Function_type*, + add_method_declaration(const std::string& name, Package*, Function_type*, Location); protected: -- 2.11.4.GIT