OSDN Git Service

Update to current version of Go library.
[pf3gnuchains/gcc-fork.git] / gcc / go / gofrontend / types.cc
index e33b349..bf19216 100644 (file)
@@ -1432,7 +1432,7 @@ Type::methods_constructor(Gogo* gogo, Type* methods_type,
        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);
 }
@@ -1444,7 +1444,8 @@ Type::methods_constructor(Gogo* gogo, Type* methods_type,
 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;
 
@@ -1487,6 +1488,25 @@ Type::method_constructor(Gogo*, Type* method_type,
 
   ++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;
@@ -2779,14 +2799,7 @@ Function_type::type_descriptor_params(Type* params_type,
                + (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)
     {
@@ -4822,9 +4835,10 @@ Array_type::make_array_type_descriptor_type()
       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);
@@ -4891,6 +4905,11 @@ Array_type::array_type_descriptor(Gogo* gogo, Named_type* name)
   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));
 
@@ -5375,8 +5394,9 @@ Channel_type::do_make_expression_tree(Translate_context* context,
   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;
 
@@ -5402,8 +5422,8 @@ Channel_type::do_make_expression_tree(Translate_context* context,
                                "__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)
@@ -6242,7 +6262,16 @@ Interface_type::do_reflection(Gogo* gogo, std::string* ret) const
          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);