Commit 817b15ca by Ian Lance Taylor

Use backend interface for slice types.

From-SVN: r173415
parent a78079c4
...@@ -1936,38 +1936,6 @@ Gogo::ptr_go_string_constant_tree(const std::string& val) ...@@ -1936,38 +1936,6 @@ Gogo::ptr_go_string_constant_tree(const std::string& val)
return build_fold_addr_expr(decl); 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 // 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 // the slice. VALUES is the value pointer and COUNT is the number of
// entries. If CAPACITY is not NULL, it is the capacity; otherwise // 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, ...@@ -2011,21 +1979,6 @@ Gogo::slice_constructor(tree slice_type_tree, tree values, tree count,
return build_constructor(slice_type_tree, init); 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. // Build a map descriptor for a map of type MAPTYPE.
tree tree
......
...@@ -465,16 +465,6 @@ class Gogo ...@@ -465,16 +465,6 @@ class Gogo
static void static void
mark_fndecl_as_builtin_library(tree fndecl); 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 // Build a constructor for a slice. SLICE_TYPE_TREE is the type of
// the slice. VALUES points to the values. COUNT is the size, // the slice. VALUES points to the values. COUNT is the size,
// CAPACITY is the capacity. If CAPACITY is NULL, it is set to // CAPACITY is the capacity. If CAPACITY is NULL, it is set to
...@@ -483,11 +473,6 @@ class Gogo ...@@ -483,11 +473,6 @@ class Gogo
slice_constructor(tree slice_type_tree, tree values, tree count, slice_constructor(tree slice_type_tree, tree values, tree count,
tree capacity); 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. // Build a map descriptor.
tree tree
map_descriptor(Map_type*); map_descriptor(Map_type*);
......
...@@ -4399,6 +4399,41 @@ Array_type::get_length_tree(Gogo* gogo) ...@@ -4399,6 +4399,41 @@ Array_type::get_length_tree(Gogo* gogo)
return this->length_tree_; 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 // 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 // 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 // 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) ...@@ -4409,8 +4444,9 @@ Array_type::do_get_tree(Gogo* gogo)
{ {
if (this->length_ == NULL) if (this->length_ == NULL)
{ {
tree struct_type = gogo->slice_type_tree(void_type_node); std::vector<Backend::Btyped_identifier> bfields;
return this->fill_in_slice_tree(gogo, struct_type); get_backend_slice_fields(gogo, this, &bfields);
return type_to_tree(gogo->backend()->struct_type(bfields));
} }
else else
{ {
...@@ -4436,26 +4472,6 @@ Array_type::get_backend_length(Gogo* gogo) ...@@ -4436,26 +4472,6 @@ Array_type::get_backend_length(Gogo* gogo)
return tree_to_expr(this->get_length_tree(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. // Return an initializer for an array type.
tree tree
...@@ -7168,13 +7184,12 @@ Named_type::create_placeholder(Gogo* gogo) ...@@ -7168,13 +7184,12 @@ Named_type::create_placeholder(Gogo* gogo)
case TYPE_ARRAY: case TYPE_ARRAY:
if (base->is_open_array_type()) 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 else
{ bt = gogo->backend()->placeholder_array_type(this->name(),
bt = gogo->backend()->placeholder_array_type(this->name(), this->location_);
this->location_); set_name = false;
set_name = false;
}
break; break;
case TYPE_INTERFACE: case TYPE_INTERFACE:
...@@ -7199,6 +7214,16 @@ Named_type::create_placeholder(Gogo* gogo) ...@@ -7199,6 +7214,16 @@ Named_type::create_placeholder(Gogo* gogo)
bt = gogo->backend()->named_type(this->name(), bt, this->location_); bt = gogo->backend()->named_type(this->name(), bt, this->location_);
this->named_btype_ = bt; 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. // Get a tree for a named type.
...@@ -7255,6 +7280,7 @@ Named_type::do_get_tree(Gogo* gogo) ...@@ -7255,6 +7280,7 @@ Named_type::do_get_tree(Gogo* gogo)
case TYPE_MAP: case TYPE_MAP:
case TYPE_CHANNEL: case TYPE_CHANNEL:
case TYPE_STRUCT: case TYPE_STRUCT:
case TYPE_ARRAY:
case TYPE_INTERFACE: case TYPE_INTERFACE:
return type_to_tree(bt); return type_to_tree(bt);
...@@ -7294,22 +7320,6 @@ Named_type::do_get_tree(Gogo* gogo) ...@@ -7294,22 +7320,6 @@ Named_type::do_get_tree(Gogo* gogo)
bt = gogo->backend()->error_type(); bt = gogo->backend()->error_type();
return type_to_tree(bt); 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: default:
case TYPE_SINK: case TYPE_SINK:
case TYPE_CALL_MULTIPLE_RESULT: case TYPE_CALL_MULTIPLE_RESULT:
......
...@@ -2068,10 +2068,6 @@ class Array_type : public Type ...@@ -2068,10 +2068,6 @@ class Array_type : public Type
Bexpression* Bexpression*
get_backend_length(Gogo*); get_backend_length(Gogo*);
// Fill in the fields for a named slice type.
tree
fill_in_slice_tree(Gogo*, tree);
static Type* static Type*
make_array_type_descriptor_type(); make_array_type_descriptor_type();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment