OSDN Git Service

compiler: Fix backend representation for interface methods.
[pf3gnuchains/gcc-fork.git] / gcc / go / gofrontend / types.cc
index 13cd48a..4ed54bb 100644 (file)
@@ -2595,7 +2595,7 @@ Integer_type::do_get_backend(Gogo* gogo)
 Expression*
 Integer_type::do_type_descriptor(Gogo* gogo, Named_type* name)
 {
-  go_assert(name != NULL);
+  go_assert(name != NULL || saw_errors());
   return this->plain_type_descriptor(gogo, this->runtime_type_kind_, name);
 }
 
@@ -2730,7 +2730,7 @@ Float_type::do_get_backend(Gogo* gogo)
 Expression*
 Float_type::do_type_descriptor(Gogo* gogo, Named_type* name)
 {
-  go_assert(name != NULL);
+  go_assert(name != NULL || saw_errors());
   return this->plain_type_descriptor(gogo, this->runtime_type_kind_, name);
 }
 
@@ -2857,7 +2857,7 @@ Complex_type::do_get_backend(Gogo* gogo)
 Expression*
 Complex_type::do_type_descriptor(Gogo* gogo, Named_type* name)
 {
-  go_assert(name != NULL);
+  go_assert(name != NULL || saw_errors());
   return this->plain_type_descriptor(gogo, this->runtime_type_kind_, name);
 }
 
@@ -6886,10 +6886,37 @@ get_backend_interface_fields(Gogo* gogo, Interface_type* type,
        p != type->methods()->end();
        ++p, ++i)
     {
+      // The type of the method in Go only includes the parameters.
+      // The actual method also has a receiver, which is always a
+      // pointer.  We need to add that pointer type here in order to
+      // generate the correct type for the backend.
+      Function_type* ft = p->type()->function_type();
+      go_assert(ft->receiver() == NULL);
+
+      const Typed_identifier_list* params = ft->parameters();
+      Typed_identifier_list* mparams = new Typed_identifier_list();
+      if (params != NULL)
+       mparams->reserve(params->size() + 1);
+      Type* vt = Type::make_pointer_type(Type::make_void_type());
+      mparams->push_back(Typed_identifier("", vt, ft->location()));
+      if (params != NULL)
+       {
+         for (Typed_identifier_list::const_iterator pp = params->begin();
+              pp != params->end();
+              ++pp)
+           mparams->push_back(*pp);
+       }
+
+      Typed_identifier_list* mresults = (ft->results() == NULL
+                                        ? NULL
+                                        : ft->results()->copy());
+      Function_type* mft = Type::make_function_type(NULL, mparams, mresults,
+                                                   ft->location());
+
       mfields[i].name = Gogo::unpack_hidden_name(p->name());
       mfields[i].btype = (use_placeholder
-                         ? p->type()->get_backend_placeholder(gogo)
-                         : p->type()->get_backend(gogo));
+                         ? mft->get_backend_placeholder(gogo)
+                         : mft->get_backend(gogo));
       mfields[i].location = loc;
       // Sanity check: the names should be sorted.
       go_assert(p->name() > last_name);