@@ -245,7 +245,7 @@
return ptype == NULL ? NULL : ptype->points_to();
}
-// Return whether this is an open array type.
+// Return whether this is a slice type.
bool
Type::is_slice_type() const
@@ -5839,14 +5839,85 @@
gogo->add_statement(s);
}
-// Get a tree for the length of a fixed array. The length may be
+// 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, bool use_placeholder,
+ std::vector<Backend::Btyped_identifier>* bfields)
+{
+ bfields->resize(3);
+
+ Type* pet = Type::make_pointer_type(type->element_type());
+ Btype* pbet = (use_placeholder
+ ? pet->get_backend_placeholder(gogo)
+ : pet->get_backend(gogo));
+ Location ploc = Linemap::predeclared_location();
+
+ Backend::Btyped_identifier* p = &(*bfields)[0];
+ p->name = "__values";
+ p->btype = pbet;
+ p->location = ploc;
+
+ Type* int_type = Type::lookup_integer_type("int");
+
+ p = &(*bfields)[1];
+ p->name = "__count";
+ p->btype = int_type->get_backend(gogo);
+ p->location = ploc;
+
+ p = &(*bfields)[2];
+ p->name = "__capacity";
+ p->btype = int_type->get_backend(gogo);
+ p->location = ploc;
+}
+
+// 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. A slice is a struct with three
+// fields: a data pointer, the length, and the capacity.
+
+Btype*
+Array_type::do_get_backend(Gogo* gogo)
+{
+ if (this->length_ == NULL)
+ {
+ std::vector<Backend::Btyped_identifier> bfields;
+ get_backend_slice_fields(gogo, this, false, &bfields);
+ return gogo->backend()->struct_type(bfields);
+ }
+ else
+ {
+ Btype* element = this->get_backend_element(gogo, false);
+ Bexpression* len = this->get_backend_length(gogo);
+ return gogo->backend()->array_type(element, len);
+ }
+}
+
+// Return the backend representation of the element type.
+
+Btype*
+Array_type::get_backend_element(Gogo* gogo, bool use_placeholder)
+{
+ if (use_placeholder)
+ return this->element_type_->get_backend_placeholder(gogo);
+ else
+ return this->element_type_->get_backend(gogo);
+}
+
+// Return the backend representation of the length. The length may be
// computed using a function call, so we must only evaluate it once.
-tree
-Array_type::get_length_tree(Gogo* gogo)
+Bexpression*
+Array_type::get_backend_length(Gogo* gogo)
{
go_assert(this->length_ != NULL);
- if (this->length_tree_ == NULL_TREE)
+ if (this->blength_ == NULL)
{
Numeric_constant nc;
mpz_t val;
@@ -5854,8 +5925,8 @@
{
if (mpz_sgn(val) < 0)
{
- this->length_tree_ = error_mark_node;
- return this->length_tree_;
+ this->blength_ = gogo->backend()->error_expression();
+ return this->blength_;
}
Type* t = nc.type();
if (t == NULL)
@@ -5863,9 +5934,8 @@
else if (t->is_abstract())
t = t->make_non_abstract_type();
Btype* btype = t->get_backend(gogo);
- Bexpression* iexpr =
- gogo->backend()->integer_constant_expression(btype, val);
- this->length_tree_ = expr_to_tree(iexpr);
+ this->blength_ =
+ gogo->backend()->integer_constant_expression(btype, val);
mpz_clear(val);
}
else
@@ -5873,97 +5943,15 @@
// Make up a translation context for the array length
// expression. FIXME: This won't work in general.
Translate_context context(gogo, NULL, NULL, NULL);
- tree len = this->length_->get_tree(&context);
- if (len != error_mark_node)
- {
- Type* int_type = Type::lookup_integer_type("int");
- tree int_type_tree = type_to_tree(int_type->get_backend(gogo));
- len = convert_to_integer(int_type_tree, len);
- len = save_expr(len);
- }
- this->length_tree_ = len;
- }
- }
- 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, bool use_placeholder,
- std::vector<Backend::Btyped_identifier>* bfields)
-{
- bfields->resize(3);
-
- Type* pet = Type::make_pointer_type(type->element_type());
- Btype* pbet = (use_placeholder
- ? pet->get_backend_placeholder(gogo)
- : pet->get_backend(gogo));
- Location ploc = Linemap::predeclared_location();
-
- Backend::Btyped_identifier* p = &(*bfields)[0];
- p->name = "__values";
- p->btype = pbet;
- p->location = ploc;
-
- Type* int_type = Type::lookup_integer_type("int");
-
- p = &(*bfields)[1];
- p->name = "__count";
- p->btype = int_type->get_backend(gogo);
- p->location = ploc;
-
- p = &(*bfields)[2];
- p->name = "__capacity";
- p->btype = int_type->get_backend(gogo);
- p->location = ploc;
-}
-
-// 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
-// fields: a data pointer, the length, and the capacity.
-
-Btype*
-Array_type::do_get_backend(Gogo* gogo)
-{
- if (this->length_ == NULL)
- {
- std::vector<Backend::Btyped_identifier> bfields;
- get_backend_slice_fields(gogo, this, false, &bfields);
- return gogo->backend()->struct_type(bfields);
- }
- else
- {
- Btype* element = this->get_backend_element(gogo, false);
- Bexpression* len = this->get_backend_length(gogo);
- return gogo->backend()->array_type(element, len);
- }
-}
-
-// Return the backend representation of the element type.
-
-Btype*
-Array_type::get_backend_element(Gogo* gogo, bool use_placeholder)
-{
- if (use_placeholder)
- return this->element_type_->get_backend_placeholder(gogo);
- else
- return this->element_type_->get_backend(gogo);
-}
-
-// Return the backend representation of the length.
-
-Bexpression*
-Array_type::get_backend_length(Gogo* gogo)
-{
- return tree_to_expr(this->get_length_tree(gogo));
+ this->blength_ = tree_to_expr(this->length_->get_tree(&context));
+
+ Btype* ibtype = Type::lookup_integer_type("int")->get_backend(gogo);
+ this->blength_ =
+ gogo->backend()->convert_expression(ibtype, this->blength_,
+ this->length_->location());
+ }
+ }
+ return this->blength_;
}
// Finish backend representation of the array.
@@ -5997,7 +5985,7 @@
array->location());
}
- // Open array.
+ // Slice.
return Expression::make_slice_info(array,
Expression::SLICE_INFO_VALUE_POINTER,
array->location());
@@ -6012,7 +6000,7 @@
if (this->length_ != NULL)
return this->length_;
- // This is an open array. We need to read the length field.
+ // This is a slice. We need to read the length field.
return Expression::make_slice_info(array, Expression::SLICE_INFO_LENGTH,
array->location());
}
@@ -6026,7 +6014,7 @@
if (this->length_ != NULL)
return this->length_;
- // This is an open array. We need to read the capacity field.
+ // This is a slice. We need to read the capacity field.
return Expression::make_slice_info(array, Expression::SLICE_INFO_CAPACITY,
array->location());
}
@@ -2305,7 +2305,7 @@
public:
Array_type(Type* element_type, Expression* length)
: Type(TYPE_ARRAY),
- element_type_(element_type), length_(length), length_tree_(NULL)
+ element_type_(element_type), length_(length), blength_(NULL)
{ }
// Return the element type.
@@ -2313,7 +2313,7 @@
element_type() const
{ return this->element_type_; }
- // Return the length. This will return NULL for an open array.
+ // Return the length. This will return NULL for a slice.
Expression*
length() const
{ return this->length_; }
@@ -2407,9 +2407,6 @@
bool
verify_length();
- tree
- get_length_tree(Gogo*);
-
Expression*
array_type_descriptor(Gogo*, Named_type*);
@@ -2420,8 +2417,9 @@
Type* element_type_;
// The number of elements. This may be NULL.
Expression* length_;
- // The length as a tree. We only want to compute this once.
- tree length_tree_;
+ // The backend representation of the length.
+ // We only want to compute this once.
+ Bexpression* blength_;
};
// The type of a map.