OSDN Git Service

compiler: Permit importing a method to a type being defined.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 2 Feb 2012 18:32:09 +0000 (18:32 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 2 Feb 2012 18:32:09 +0000 (18:32 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183840 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/gogo.h
gcc/go/gofrontend/import.cc
gcc/go/gofrontend/types.cc
gcc/go/gofrontend/types.h

index c65e47f..fafd04f 100644 (file)
@@ -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;
 }
index 2231e5d..008c8a0 100644 (file)
@@ -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
index de7edc9..44ffda6 100644 (file)
@@ -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.
index 525d33a..4020399 100644 (file)
@@ -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.
index 4e45b99..4398ef1 100644 (file)
@@ -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: