p != smethods.end();
++p)
vals->push_back(this->method_constructor(gogo, method_type, p->first,
- p->second));
+ p->second, only_value_methods));
return Expression::make_slice_composite_literal(methods_type, vals, bloc);
}
Expression*
Type::method_constructor(Gogo*, Type* method_type,
const std::string& method_name,
- const Method* m) const
+ const Method* m,
+ bool only_value_methods) const
{
source_location bloc = BUILTINS_LOCATION;
++p;
go_assert(p->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));
++p;
+ (receiver != NULL ? 1 : 0));
if (receiver != NULL)
- {
- Type* rtype = receiver->type();
- // The receiver is always passed as a pointer. FIXME: Is this
- // right? Should that fact affect the type descriptor?
- if (rtype->points_to() == NULL)
- rtype = Type::make_pointer_type(rtype);
- vals->push_back(Expression::make_type_descriptor(rtype, bloc));
- }
+ vals->push_back(Expression::make_type_descriptor(receiver->type(), bloc));
if (params != NULL)
{
Type* uintptr_type = Type::lookup_integer_type("uintptr");
Struct_type* sf =
- Type::make_builtin_struct_type(3,
+ Type::make_builtin_struct_type(4,
"", tdt,
"elem", ptdt,
+ "slice", ptdt,
"len", uintptr_type);
ret = Type::make_builtin_named_type("ArrayType", sf);
vals->push_back(Expression::make_type_descriptor(this->element_type_, bloc));
++p;
+ go_assert(p->field_name() == "slice");
+ Type* slice_type = Type::make_array_type(this->element_type_, NULL);
+ vals->push_back(Expression::make_type_descriptor(slice_type, bloc));
+
+ ++p;
go_assert(p->field_name() == "len");
vals->push_back(Expression::make_cast(p->type(), this->length_, bloc));
Gogo* gogo = context->gogo();
tree channel_type = type_to_tree(this->get_backend(gogo));
- tree element_tree = type_to_tree(this->element_type_->get_backend(gogo));
- tree element_size_tree = size_in_bytes(element_tree);
+ Type* ptdt = Type::make_type_descriptor_ptr_type();
+ tree element_type_descriptor =
+ this->element_type_->type_descriptor_pointer(gogo);
tree bad_index = NULL_TREE;
"__go_new_channel",
2,
channel_type,
- sizetype,
- element_size_tree,
+ type_to_tree(ptdt->get_backend(gogo)),
+ element_type_descriptor,
sizetype,
expr_tree);
if (ret == error_mark_node)
if (p != this->methods_->begin())
ret->append(";");
ret->push_back(' ');
- ret->append(Gogo::unpack_hidden_name(p->name()));
+ if (!Gogo::is_hidden_name(p->name()))
+ ret->append(p->name());
+ else
+ {
+ // This matches what the gc compiler does.
+ std::string prefix = Gogo::hidden_name_prefix(p->name());
+ ret->append(prefix.substr(prefix.find('.') + 1));
+ ret->push_back('.');
+ ret->append(Gogo::unpack_hidden_name(p->name()));
+ }
std::string sub = p->type()->reflection(gogo);
go_assert(sub.compare(0, 4, "func") == 0);
sub = sub.substr(4);