diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-05-06 01:14:34 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-05-06 01:14:34 +0000 |
commit | 0c2b1bb7b665e77a4f0ebe462447abab90b87ecf (patch) | |
tree | a1a3d3366149c1edfb32fc9dda9279363a2182ab /gcc | |
parent | 9239c1b47dd6fe540d7035d1c9a1f393122affb7 (diff) | |
download | gcc-0c2b1bb7b665e77a4f0ebe462447abab90b87ecf.zip gcc-0c2b1bb7b665e77a4f0ebe462447abab90b87ecf.tar.gz gcc-0c2b1bb7b665e77a4f0ebe462447abab90b87ecf.tar.bz2 |
compiler: Use backend interface for array length.
From-SVN: r210093
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/types.cc | 98 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.h | 12 |
2 files changed, 48 insertions, 62 deletions
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 91a535f..0ff9c76 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -245,7 +245,7 @@ Type::points_to() const 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,54 +5839,6 @@ Array_type::write_equal_function(Gogo* gogo, Named_type* name) gogo->add_statement(s); } -// Get a tree for the length of a fixed array. The length may be -// computed using a function call, so we must only evaluate it once. - -tree -Array_type::get_length_tree(Gogo* gogo) -{ - go_assert(this->length_ != NULL); - if (this->length_tree_ == NULL_TREE) - { - Numeric_constant nc; - mpz_t val; - if (this->length_->numeric_constant_value(&nc) && nc.to_int(&val)) - { - if (mpz_sgn(val) < 0) - { - this->length_tree_ = error_mark_node; - return this->length_tree_; - } - Type* t = nc.type(); - if (t == NULL) - t = Type::lookup_integer_type("int"); - 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); - mpz_clear(val); - } - else - { - // 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. @@ -5927,7 +5879,7 @@ get_backend_slice_fields(Gogo* gogo, Array_type* type, bool use_placeholder, // 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 +// just like an array in C. A slice is a struct with three // fields: a data pointer, the length, and the capacity. Btype* @@ -5958,12 +5910,48 @@ Array_type::get_backend_element(Gogo* gogo, bool use_placeholder) return this->element_type_->get_backend(gogo); } -// Return the backend representation of the length. +// Return the backend representation of the length. The length may be +// computed using a function call, so we must only evaluate it once. Bexpression* Array_type::get_backend_length(Gogo* gogo) { - return tree_to_expr(this->get_length_tree(gogo)); + go_assert(this->length_ != NULL); + if (this->blength_ == NULL) + { + Numeric_constant nc; + mpz_t val; + if (this->length_->numeric_constant_value(&nc) && nc.to_int(&val)) + { + if (mpz_sgn(val) < 0) + { + this->blength_ = gogo->backend()->error_expression(); + return this->blength_; + } + Type* t = nc.type(); + if (t == NULL) + t = Type::lookup_integer_type("int"); + else if (t->is_abstract()) + t = t->make_non_abstract_type(); + Btype* btype = t->get_backend(gogo); + this->blength_ = + gogo->backend()->integer_constant_expression(btype, val); + mpz_clear(val); + } + else + { + // Make up a translation context for the array length + // expression. FIXME: This won't work in general. + Translate_context context(gogo, NULL, NULL, NULL); + 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_type::get_value_pointer(Gogo*, Expression* array) const array->location()); } - // Open array. + // Slice. return Expression::make_slice_info(array, Expression::SLICE_INFO_VALUE_POINTER, array->location()); @@ -6012,7 +6000,7 @@ Array_type::get_length(Gogo*, Expression* array) const 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 @@ Array_type::get_capacity(Gogo*, Expression* array) const 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()); } diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index d2ca1bf..b2a49ac3 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -2305,7 +2305,7 @@ class Array_type : public Type 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 @@ class Array_type : public Type 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 @@ class Array_type : public Type bool verify_length(); - tree - get_length_tree(Gogo*); - Expression* array_type_descriptor(Gogo*, Named_type*); @@ -2420,8 +2417,9 @@ class Array_type : public Type 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. |