aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-02-02 18:32:09 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-02-02 18:32:09 +0000
commitf22f4fc1536bd76895feb85bb501b015f18fd452 (patch)
tree93f917b35f3b8ff1329d0a38d7413c19994d2dba /gcc
parent5ee770bf9e6941a2d1f8d59e9e663fa08c818b42 (diff)
downloadgcc-f22f4fc1536bd76895feb85bb501b015f18fd452.zip
gcc-f22f4fc1536bd76895feb85bb501b015f18fd452.tar.gz
gcc-f22f4fc1536bd76895feb85bb501b015f18fd452.tar.bz2
compiler: Permit importing a method to a type being defined.
From-SVN: r183840
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/gogo.cc7
-rw-r--r--gcc/go/gofrontend/gogo.h4
-rw-r--r--gcc/go/gofrontend/import.cc29
-rw-r--r--gcc/go/gofrontend/types.cc3
-rw-r--r--gcc/go/gofrontend/types.h2
5 files changed, 32 insertions, 13 deletions
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index c65e47f..fafd04f 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 2231e5d..008c8a0 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 de7edc9..44ffda6 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 525d33a..4020399 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 4e45b99..4398ef1 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: