This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Go patch committed: Permit importing a method to a type being defined


In a slightly complex case (I am adding a test case to the master Go
testsuite) it is possible for the importer to see a method for a type
which is in the process of being imported and is therefore not fully
defined.  This was causing the compiler to complain about an undefined
type during the import.  This patch fixes the problem.  Bootstrapped and
ran Go testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

diff -r 59d85958d284 go/gogo.cc
--- a/go/gogo.cc	Wed Feb 01 22:38:55 2012 -0800
+++ b/go/gogo.cc	Thu Feb 02 10:25:58 2012 -0800
@@ -880,7 +880,7 @@
       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 @@
 
 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 -r 59d85958d284 go/gogo.h
--- a/go/gogo.h	Wed Feb 01 22:38:55 2012 -0800
+++ b/go/gogo.h	Thu Feb 02 10:25:58 2012 -0800
@@ -1621,8 +1621,8 @@
 
   // 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 -r 59d85958d284 go/import.cc
--- a/go/import.cc	Wed Feb 01 22:38:55 2012 -0800
+++ b/go/import.cc	Thu Feb 02 10:25:58 2012 -0800
@@ -441,12 +441,29 @@
   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 @@
 	{
 	  // 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 -r 59d85958d284 go/types.cc
--- a/go/types.cc	Wed Feb 01 22:38:55 2012 -0800
+++ b/go/types.cc	Thu Feb 02 10:25:58 2012 -0800
@@ -9115,6 +9115,7 @@
 
 Named_object*
 Forward_declaration_type::add_method_declaration(const std::string& name,
+						 Package* package,
 						 Function_type* type,
 						 Location location)
 {
@@ -9122,7 +9123,7 @@
   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 -r 59d85958d284 go/types.h
--- a/go/types.h	Wed Feb 01 22:38:55 2012 -0800
+++ b/go/types.h	Thu Feb 02 10:25:58 2012 -0800
@@ -2937,7 +2937,7 @@
 
   // 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:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]