From d6007535e639e34b9a73fd3967d1b7f135414386 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 24 Feb 2011 03:37:57 +0000 Subject: Handle an array of pointers to itself. From-SVN: r170454 --- gcc/go/gofrontend/types.cc | 68 +++++++++++++++++++++++++++++++++------------- gcc/go/gofrontend/types.h | 6 +++- 2 files changed, 54 insertions(+), 20 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 8ce39b7..1e39731 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -4442,33 +4442,59 @@ 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_tree(gogo, struct_type); + return this->fill_in_slice_tree(gogo, struct_type); } else { - tree element_type_tree = this->element_type_->get_tree(gogo); - tree length_tree = this->get_length_tree(gogo); - if (element_type_tree == error_mark_node - || length_tree == error_mark_node) - return error_mark_node; + tree array_type = make_node(ARRAY_TYPE); + return this->fill_in_array_tree(gogo, array_type); + } +} - length_tree = fold_convert(sizetype, length_tree); +// Fill in the fields for an array type. This is used for named array +// types. - // build_index_type takes the maximum index, which is one less - // than the length. - tree index_type = build_index_type(fold_build2(MINUS_EXPR, sizetype, - length_tree, - size_one_node)); +tree +Array_type::fill_in_array_tree(Gogo* gogo, tree array_type) +{ + gcc_assert(this->length_ != NULL); - return build_array_type(element_type_tree, index_type); - } + tree element_type_tree = this->element_type_->get_tree(gogo); + tree length_tree = this->get_length_tree(gogo); + if (element_type_tree == error_mark_node + || length_tree == error_mark_node) + return error_mark_node; + + length_tree = fold_convert(sizetype, length_tree); + + // build_index_type takes the maximum index, which is one less than + // the length. + tree index_type = build_index_type(fold_build2(MINUS_EXPR, sizetype, + length_tree, + size_one_node)); + + TREE_TYPE(array_type) = element_type_tree; + TYPE_DOMAIN(array_type) = index_type; + TYPE_ADDR_SPACE(array_type) = TYPE_ADDR_SPACE(element_type_tree); + layout_type(array_type); + + if (TYPE_STRUCTURAL_EQUALITY_P(element_type_tree) + || TYPE_STRUCTURAL_EQUALITY_P(index_type)) + SET_TYPE_STRUCTURAL_EQUALITY(array_type); + else if (TYPE_CANONICAL(element_type_tree) != element_type_tree + || TYPE_CANONICAL(index_type) != index_type) + TYPE_CANONICAL(array_type) = + build_array_type(TYPE_CANONICAL(element_type_tree), + TYPE_CANONICAL(index_type)); + + return array_type; } // Fill in the fields for a slice type. This is used for named slice // types. tree -Array_type::fill_in_tree(Gogo* gogo, tree struct_type) +Array_type::fill_in_slice_tree(Gogo* gogo, tree struct_type) { gcc_assert(this->length_ == NULL); @@ -7129,15 +7155,19 @@ Named_type::do_get_tree(Gogo* gogo) break; case TYPE_ARRAY: + if (this->named_tree_ != NULL_TREE) + return this->named_tree_; if (!this->is_open_array_type()) - t = Type::get_named_type_tree(gogo, this->type_); + { + t = make_node(ARRAY_TYPE); + this->named_tree_ = t; + t = this->type_->array_type()->fill_in_array_tree(gogo, t); + } else { - if (this->named_tree_ != NULL_TREE) - return this->named_tree_; t = gogo->slice_type_tree(void_type_node); this->named_tree_ = t; - t = this->type_->array_type()->fill_in_tree(gogo, t); + t = this->type_->array_type()->fill_in_slice_tree(gogo, t); } if (t == error_mark_node) return error_mark_node; diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index b9e8caf..b428077 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -2050,9 +2050,13 @@ class Array_type : public Type static Array_type* do_import(Import*); + // Fill in the fields for a named array type. + tree + fill_in_array_tree(Gogo*, tree); + // Fill in the fields for a named slice type. tree - fill_in_tree(Gogo*, tree); + fill_in_slice_tree(Gogo*, tree); protected: int -- cgit v1.1