aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-05-05 05:22:12 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-05-05 05:22:12 +0000
commit817b15caf0f81a539af9d74cd47e6bc0727881bb (patch)
tree9431f70a212177b301cdcd08958d3469585bcf5d /gcc/go
parenta78079c49b556474080ef7336be1afa0e50b3ab1 (diff)
downloadgcc-817b15caf0f81a539af9d74cd47e6bc0727881bb.zip
gcc-817b15caf0f81a539af9d74cd47e6bc0727881bb.tar.gz
gcc-817b15caf0f81a539af9d74cd47e6bc0727881bb.tar.bz2
Use backend interface for slice types.
From-SVN: r173415
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/gogo-tree.cc47
-rw-r--r--gcc/go/gofrontend/gogo.h15
-rw-r--r--gcc/go/gofrontend/types.cc98
-rw-r--r--gcc/go/gofrontend/types.h4
4 files changed, 54 insertions, 110 deletions
diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc
index b1ccfc3..2ff94f6 100644
--- a/gcc/go/gofrontend/gogo-tree.cc
+++ b/gcc/go/gofrontend/gogo-tree.cc
@@ -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
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index 6a0b994..0c524f0 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -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*);
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index fed1447..667f3e5 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -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:
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 3b4d5f2..37199de 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -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();