aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2013-12-12 01:08:52 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2013-12-12 01:08:52 +0000
commit547a4168791b7ae9543215aba3ca6184c31bb37e (patch)
tree6d22f3392a75c3aaa5aa1da655668fca943b1d10 /gcc
parent24fd676aa8b79e264e3b6dac48f7d18d0921761e (diff)
downloadgcc-547a4168791b7ae9543215aba3ca6184c31bb37e.zip
gcc-547a4168791b7ae9543215aba3ca6184c31bb37e.tar.gz
gcc-547a4168791b7ae9543215aba3ca6184c31bb37e.tar.bz2
compiler, reflect, runtime: Implement method values in reflect.
From-SVN: r205913
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/types.cc49
-rw-r--r--gcc/go/gofrontend/types.h6
2 files changed, 35 insertions, 20 deletions
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 8c5d038..33c23e5 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -2261,26 +2261,9 @@ Type::method_constructor(Gogo*, Type* method_type,
++p;
go_assert(p->is_field_name("typ"));
- if (!only_value_methods && m->is_value_method())
- {
- // This is a value method on a pointer type. Change the type of
- // the method to use a pointer receiver. The implementation
- // always uses a pointer receiver anyhow.
- Type* rtype = mtype->receiver()->type();
- Type* prtype = Type::make_pointer_type(rtype);
- Typed_identifier* receiver =
- new Typed_identifier(mtype->receiver()->name(), prtype,
- mtype->receiver()->location());
- mtype = Type::make_function_type(receiver,
- (mtype->parameters() == NULL
- ? NULL
- : mtype->parameters()->copy()),
- (mtype->results() == NULL
- ? NULL
- : mtype->results()->copy()),
- mtype->location());
- }
- vals->push_back(Expression::make_type_descriptor(mtype, bloc));
+ bool want_pointer_receiver = !only_value_methods && m->is_value_method();
+ nonmethod_type = mtype->copy_with_receiver_as_param(want_pointer_receiver);
+ vals->push_back(Expression::make_type_descriptor(nonmethod_type, bloc));
++p;
go_assert(p->is_field_name("tfn"));
@@ -4008,6 +3991,32 @@ Function_type::copy_with_receiver(Type* receiver_type) const
return ret;
}
+// Make a copy of a function type with the receiver as the first
+// parameter.
+
+Function_type*
+Function_type::copy_with_receiver_as_param(bool want_pointer_receiver) const
+{
+ go_assert(this->is_method());
+ Typed_identifier_list* new_params = new Typed_identifier_list();
+ Type* rtype = this->receiver_->type();
+ if (want_pointer_receiver)
+ rtype = Type::make_pointer_type(rtype);
+ Typed_identifier receiver(this->receiver_->name(), rtype,
+ this->receiver_->location());
+ new_params->push_back(receiver);
+ const Typed_identifier_list* orig_params = this->parameters_;
+ if (orig_params != NULL && !orig_params->empty())
+ {
+ for (Typed_identifier_list::const_iterator p = orig_params->begin();
+ p != orig_params->end();
+ ++p)
+ new_params->push_back(*p);
+ }
+ return Type::make_function_type(NULL, new_params, this->results_,
+ this->location_);
+}
+
// Make a copy of a function type ignoring any receiver and adding a
// closure parameter.
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 1bd8ce6..9f96591 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -1797,6 +1797,12 @@ class Function_type : public Type
Function_type*
copy_with_receiver(Type*) const;
+ // Return a copy of this type with the receiver treated as the first
+ // parameter. If WANT_POINTER_RECEIVER is true, the receiver is
+ // forced to be a pointer.
+ Function_type*
+ copy_with_receiver_as_param(bool want_pointer_receiver) const;
+
// Return a copy of this type ignoring any receiver and using dummy
// names for all parameters. This is used for thunks for method
// values.