From: Ian Lance Taylor Date: Thu, 5 May 2011 05:22:12 +0000 (+0000) Subject: Use backend interface for slice types. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=817b15caf0f81a539af9d74cd47e6bc0727881bb;p=gcc.git Use backend interface for slice types. From-SVN: r173415 --- diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc index b1ccfc3ae62..2ff94f64e5b 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 6a0b994ab60..0c524f029fc 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 fed14473d69..667f3e59095 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* 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 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 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 3b4d5f22953..37199de7808 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();