aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-02-17 20:00:34 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-02-17 20:00:34 +0000
commit5a815b930afa24b49723919b0e7da0bd04028d28 (patch)
tree92b83cc481feffe8520d2878ed03b41ec6e6b74f /gcc/go
parent7a6cb708b1a23103a7fab3e3d01b0e3933dc6c4a (diff)
downloadgcc-5a815b930afa24b49723919b0e7da0bd04028d28.zip
gcc-5a815b930afa24b49723919b0e7da0bd04028d28.tar.gz
gcc-5a815b930afa24b49723919b0e7da0bd04028d28.tar.bz2
compiler: Fix backend representation for interface methods.
From-SVN: r184348
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/types.cc31
1 files changed, 29 insertions, 2 deletions
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 61ec555..4ed54bb 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -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);