Use backend interface for slice types.
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 5 May 2011 05:22:12 +0000 (05:22 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 5 May 2011 05:22:12 +0000 (05:22 +0000)
From-SVN: r173415

gcc/go/gofrontend/gogo-tree.cc
gcc/go/gofrontend/gogo.h
gcc/go/gofrontend/types.cc
gcc/go/gofrontend/types.h

index b1ccfc3ae62b8e3cfb4241470727d5a9e9a0fbf4..2ff94f64e5bcc54296e8db4c15d23ccbf51f983d 100644 (file)
@@ -1936,38 +1936,6 @@ Gogo::ptr_go_string_constant_tree(const std::string& val)
   return build_fold_addr_expr(decl);
 }
 
-// Build the type of the struct that holds a slice for the given
-// element type.
-
-tree
-Gogo::slice_type_tree(tree element_type_tree)
-{
-  // We use int for the count and capacity fields in a slice header.
-  // This matches 6g.  The language definition guarantees that we
-  // can't allocate space of a size which does not fit in int
-  // anyhow. FIXME: integer_type_node is the the C type "int" but is
-  // not necessarily the Go type "int".  They will differ when the C
-  // type "int" has fewer than 32 bits.
-  return Gogo::builtin_struct(NULL, "__go_slice", NULL_TREE, 3,
-                             "__values",
-                             build_pointer_type(element_type_tree),
-                             "__count",
-                             integer_type_node,
-                             "__capacity",
-                             integer_type_node);
-}
-
-// Given the tree for a slice type, return the tree for the type of
-// the elements of the slice.
-
-tree
-Gogo::slice_element_type_tree(tree slice_type_tree)
-{
-  go_assert(TREE_CODE(slice_type_tree) == RECORD_TYPE
-            && POINTER_TYPE_P(TREE_TYPE(TYPE_FIELDS(slice_type_tree))));
-  return TREE_TYPE(TREE_TYPE(TYPE_FIELDS(slice_type_tree)));
-}
-
 // Build a constructor for a slice.  SLICE_TYPE_TREE is the type of
 // the slice.  VALUES is the value pointer and COUNT is the number of
 // entries.  If CAPACITY is not NULL, it is the capacity; otherwise
@@ -2011,21 +1979,6 @@ Gogo::slice_constructor(tree slice_type_tree, tree values, tree count,
   return build_constructor(slice_type_tree, init);
 }
 
-// Build a constructor for an empty slice.
-
-tree
-Gogo::empty_slice_constructor(tree slice_type_tree)
-{
-  tree element_field = TYPE_FIELDS(slice_type_tree);
-  tree ret = Gogo::slice_constructor(slice_type_tree,
-                                    fold_convert(TREE_TYPE(element_field),
-                                                 null_pointer_node),
-                                    size_zero_node,
-                                    size_zero_node);
-  TREE_CONSTANT(ret) = 1;
-  return ret;
-}
-
 // Build a map descriptor for a map of type MAPTYPE.
 
 tree
index 6a0b994ab60b2301caad7bc08dfcafd433c89d5b..0c524f029fccf82058fa2281e354063f5e4109f8 100644 (file)
@@ -465,16 +465,6 @@ class Gogo
   static void
   mark_fndecl_as_builtin_library(tree fndecl);
 
-  // Build the type of the struct that holds a slice for the given
-  // element type.
-  tree
-  slice_type_tree(tree element_type_tree);
-
-  // Given a tree for a slice type, return the tree for the element
-  // type.
-  static tree
-  slice_element_type_tree(tree slice_type_tree);
-
   // Build a constructor for a slice.  SLICE_TYPE_TREE is the type of
   // the slice.  VALUES points to the values.  COUNT is the size,
   // CAPACITY is the capacity.  If CAPACITY is NULL, it is set to
@@ -483,11 +473,6 @@ class Gogo
   slice_constructor(tree slice_type_tree, tree values, tree count,
                    tree capacity);
 
-  // Build a constructor for an empty slice.  SLICE_TYPE_TREE is the
-  // type of the slice.
-  static tree
-  empty_slice_constructor(tree slice_type_tree);
-
   // Build a map descriptor.
   tree
   map_descriptor(Map_type*);
index fed14473d69b714b4479cb2c122cfdc49267982e..667f3e5909512c6878ba4f48557282a1e6f3a359 100644 (file)
@@ -4399,6 +4399,41 @@ Array_type::get_length_tree(Gogo* gogo)
   return this->length_tree_;
 }
 
+// Get the backend representation of the fields of a slice.  This is
+// not declared in types.h so that types.h doesn't have to #include
+// backend.h.
+//
+// We use int for the count and capacity fields.  This matches 6g.
+// The language more or less assumes that we can't allocate space of a
+// size which does not fit in int.
+
+static void
+get_backend_slice_fields(Gogo* gogo, Array_type* type,
+                        std::vector<Backend::Btyped_identifier>* bfields)
+{
+  bfields->resize(3);
+
+  Type* pet = Type::make_pointer_type(type->element_type());
+  Btype* pbet = tree_to_type(pet->get_tree(gogo));
+
+  Backend::Btyped_identifier* p = &(*bfields)[0];
+  p->name = "__values";
+  p->btype = pbet;
+  p->location = UNKNOWN_LOCATION;
+
+  Type* int_type = Type::lookup_integer_type("int");
+
+  p = &(*bfields)[1];
+  p->name = "__count";
+  p->btype = tree_to_type(int_type->get_tree(gogo));
+  p->location = UNKNOWN_LOCATION;
+
+  p = &(*bfields)[2];
+  p->name = "__capacity";
+  p->btype = tree_to_type(int_type->get_tree(gogo));
+  p->location = UNKNOWN_LOCATION;
+}
+
 // Get a tree for the type of this array.  A fixed array is simply
 // represented as ARRAY_TYPE with the appropriate index--i.e., it is
 // just like an array in C.  An open array is a struct with three
@@ -4409,8 +4444,9 @@ Array_type::do_get_tree(Gogo* gogo)
 {
   if (this->length_ == NULL)
     {
-      tree struct_type = gogo->slice_type_tree(void_type_node);
-      return this->fill_in_slice_tree(gogo, struct_type);
+      std::vector<Backend::Btyped_identifier> bfields;
+      get_backend_slice_fields(gogo, this, &bfields);
+      return type_to_tree(gogo->backend()->struct_type(bfields));
     }
   else
     {
@@ -4436,26 +4472,6 @@ Array_type::get_backend_length(Gogo* gogo)
   return tree_to_expr(this->get_length_tree(gogo));
 }
 
-// Fill in the fields for a slice type.  This is used for named slice
-// types.
-
-tree
-Array_type::fill_in_slice_tree(Gogo* gogo, tree struct_type)
-{
-  go_assert(this->length_ == NULL);
-
-  tree element_type_tree = this->element_type_->get_tree(gogo);
-  if (element_type_tree == error_mark_node)
-    return error_mark_node;
-  tree field = TYPE_FIELDS(struct_type);
-  go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__values") == 0);
-  go_assert(POINTER_TYPE_P(TREE_TYPE(field))
-            && TREE_TYPE(TREE_TYPE(field)) == void_type_node);
-  TREE_TYPE(field) = build_pointer_type(element_type_tree);
-
-  return struct_type;
-}
-
 // Return an initializer for an array type.
 
 tree
@@ -7168,13 +7184,12 @@ Named_type::create_placeholder(Gogo* gogo)
 
     case TYPE_ARRAY:
       if (base->is_open_array_type())
-       bt = tree_to_type(gogo->slice_type_tree(void_type_node));
+       bt = gogo->backend()->placeholder_struct_type(this->name(),
+                                                     this->location_);
       else
-       {
-         bt = gogo->backend()->placeholder_array_type(this->name(),
-                                                      this->location_);
-         set_name = false;
-       }
+       bt = gogo->backend()->placeholder_array_type(this->name(),
+                                                    this->location_);
+      set_name = false;
       break;
 
     case TYPE_INTERFACE:
@@ -7199,6 +7214,16 @@ Named_type::create_placeholder(Gogo* gogo)
     bt = gogo->backend()->named_type(this->name(), bt, this->location_);
 
   this->named_btype_ = bt;
+
+  if (base->is_open_array_type())
+    {
+      // We do not record slices as dependencies of other types,
+      // because we can fill them in completely here.
+      std::vector<Backend::Btyped_identifier> bfields;
+      get_backend_slice_fields(gogo, base->array_type(), &bfields);
+      if (!gogo->backend()->set_placeholder_struct_type(bt, bfields))
+       this->named_btype_ = gogo->backend()->error_type();
+    }
 }
 
 // Get a tree for a named type.
@@ -7255,6 +7280,7 @@ Named_type::do_get_tree(Gogo* gogo)
     case TYPE_MAP:
     case TYPE_CHANNEL:
     case TYPE_STRUCT:
+    case TYPE_ARRAY:
     case TYPE_INTERFACE:
       return type_to_tree(bt);
 
@@ -7294,22 +7320,6 @@ Named_type::do_get_tree(Gogo* gogo)
        bt = gogo->backend()->error_type();
       return type_to_tree(bt);
 
-    case TYPE_ARRAY:
-      if (base->is_open_array_type())
-       {
-         if (this->seen_ > 0)
-           return type_to_tree(bt);
-         else
-           {
-             ++this->seen_;
-             tree t = base->array_type()->fill_in_slice_tree(gogo,
-                                                             type_to_tree(bt));
-             bt = tree_to_type(t);
-             --this->seen_;
-           }
-       }
-      return type_to_tree(bt);
-
     default:
     case TYPE_SINK:
     case TYPE_CALL_MULTIPLE_RESULT:
index 3b4d5f22953d589d04ebdde97d170387a2e81f92..37199de7808f8ecbe4a57b2236d07fc748e69c55 100644 (file)
@@ -2068,10 +2068,6 @@ class Array_type : public Type
   Bexpression*
   get_backend_length(Gogo*);
 
-  // Fill in the fields for a named slice type.
-  tree
-  fill_in_slice_tree(Gogo*, tree);
-
   static Type*
   make_array_type_descriptor_type();