Commit 4e7e7a49 by Ian Lance Taylor

More uses of backend interface for types.

From-SVN: r173507
parent c81e79b5
...@@ -845,7 +845,7 @@ Type::get_tree(Gogo* gogo) ...@@ -845,7 +845,7 @@ Type::get_tree(Gogo* gogo)
if (this->forward_declaration_type() != NULL if (this->forward_declaration_type() != NULL
|| this->named_type() != NULL) || this->named_type() != NULL)
return this->get_tree_without_hash(gogo); return type_to_tree(this->get_btype_without_hash(gogo));
if (this->is_error_type()) if (this->is_error_type())
return error_mark_node; return error_mark_node;
...@@ -865,7 +865,7 @@ Type::get_tree(Gogo* gogo) ...@@ -865,7 +865,7 @@ Type::get_tree(Gogo* gogo)
return ins.first->second; return ins.first->second;
} }
tree t = this->get_tree_without_hash(gogo); tree t = type_to_tree(this->get_btype_without_hash(gogo));
if (ins.first->second == NULL_TREE) if (ins.first->second == NULL_TREE)
ins.first->second = t; ins.first->second = t;
...@@ -884,43 +884,33 @@ Type::get_tree(Gogo* gogo) ...@@ -884,43 +884,33 @@ Type::get_tree(Gogo* gogo)
return t; return t;
} }
// Return a tree for a type without looking in the hash table for // Return the backend representation for a type without looking in the
// identical types. This is used for named types, since there is no // hash table for identical types. This is used for named types,
// point to looking in the hash table for them. // since a named type is never identical to any other type.
tree Btype*
Type::get_tree_without_hash(Gogo* gogo) Type::get_btype_without_hash(Gogo* gogo)
{ {
if (this->tree_ == NULL_TREE) if (this->tree_ == NULL_TREE)
{ {
tree t = this->do_get_tree(gogo); Btype* bt = tree_to_type(this->do_get_tree(gogo));
// For a recursive function or pointer type, we will temporarily // For a recursive function or pointer type, we will temporarily
// return a circular pointer type during the recursion. We // return a circular pointer type during the recursion. We
// don't want to record that for a forwarding type, as it may // don't want to record that for a forwarding type, as it may
// confuse us later. // confuse us later.
if (this->forward_declaration_type() != NULL if (this->forward_declaration_type() != NULL
&& gogo->backend()->is_circular_pointer_type(tree_to_type(t))) && gogo->backend()->is_circular_pointer_type(bt))
return t; return bt;
if (gogo == NULL || !gogo->named_types_are_converted()) if (gogo == NULL || !gogo->named_types_are_converted())
return t; return bt;
tree t = type_to_tree(bt);
this->tree_ = t; this->tree_ = t;
go_preserve_from_gc(t);
} }
return this->tree_; return tree_to_type(this->tree_);
}
// Return the backend representation for a type without looking in the
// hash table for identical types. This is used for named types,
// since a named type is never identical to any other type.
Btype*
Type::get_btype_without_hash(Gogo* gogo)
{
return tree_to_type(this->get_tree_without_hash(gogo));
} }
// Return a tree representing a zero initialization for this type. // Return a tree representing a zero initialization for this type.
...@@ -1596,8 +1586,8 @@ class Error_type : public Type ...@@ -1596,8 +1586,8 @@ class Error_type : public Type
protected: protected:
tree tree
do_get_tree(Gogo*) do_get_tree(Gogo* gogo)
{ return error_mark_node; } { return type_to_tree(gogo->backend()->error_type()); }
tree tree
do_get_init_tree(Gogo*, tree, bool) do_get_init_tree(Gogo*, tree, bool)
...@@ -3228,8 +3218,11 @@ class Nil_type : public Type ...@@ -3228,8 +3218,11 @@ class Nil_type : public Type
protected: protected:
tree tree
do_get_tree(Gogo*) do_get_tree(Gogo* gogo)
{ return ptr_type_node; } {
Btype* bt = gogo->backend()->pointer_type(gogo->backend()->void_type());
return type_to_tree(bt);
}
tree tree
do_get_init_tree(Gogo*, tree type_tree, bool is_clear) do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
...@@ -5064,61 +5057,44 @@ Map_type::do_check_make_expression(Expression_list* args, ...@@ -5064,61 +5057,44 @@ Map_type::do_check_make_expression(Expression_list* args,
return true; return true;
} }
// Get a tree for a map type. A map type is represented as a pointer // Get the backend representation for a map type. A map type is
// to a struct. The struct is __go_map in libgo/map.h. // represented as a pointer to a struct. The struct is __go_map in
// libgo/map.h.
tree tree
Map_type::do_get_tree(Gogo* gogo) Map_type::do_get_tree(Gogo* gogo)
{ {
static tree type_tree; static Btype* backend_map_type;
if (type_tree == NULL_TREE) if (backend_map_type == NULL)
{ {
tree struct_type = make_node(RECORD_TYPE); std::vector<Backend::Btyped_identifier> bfields(4);
tree map_descriptor_type = gogo->map_descriptor_type();
tree const_map_descriptor_type =
build_qualified_type(map_descriptor_type, TYPE_QUAL_CONST);
tree name = get_identifier("__descriptor");
tree field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name,
build_pointer_type(const_map_descriptor_type));
DECL_CONTEXT(field) = struct_type;
TYPE_FIELDS(struct_type) = field;
tree last_field = field;
name = get_identifier("__element_count"); Type* pdt = Type::make_type_descriptor_ptr_type();
field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name, sizetype); bfields[0].name = "__descriptor";
DECL_CONTEXT(field) = struct_type; bfields[0].btype = tree_to_type(pdt->get_tree(gogo));
DECL_CHAIN(last_field) = field; bfields[0].location = BUILTINS_LOCATION;
last_field = field;
name = get_identifier("__bucket_count");
field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name, sizetype);
DECL_CONTEXT(field) = struct_type;
DECL_CHAIN(last_field) = field;
last_field = field;
name = get_identifier("__buckets"); Type* uintptr_type = Type::lookup_integer_type("uintptr");
field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name, bfields[1].name = "__element_count";
build_pointer_type(ptr_type_node)); bfields[1].btype = tree_to_type(uintptr_type->get_tree(gogo));
DECL_CONTEXT(field) = struct_type; bfields[1].location = BUILTINS_LOCATION;
DECL_CHAIN(last_field) = field;
layout_type(struct_type); bfields[2].name = "__bucket_count";
bfields[2].btype = bfields[1].btype;
bfields[2].location = BUILTINS_LOCATION;
// Give the struct a name for better debugging info. Btype* bvt = gogo->backend()->void_type();
name = get_identifier("__go_map"); Btype* bpvt = gogo->backend()->pointer_type(bvt);
tree type_decl = build_decl(BUILTINS_LOCATION, TYPE_DECL, name, Btype* bppvt = gogo->backend()->pointer_type(bpvt);
struct_type); bfields[3].name = "__buckets";
DECL_ARTIFICIAL(type_decl) = 1; bfields[3].btype = bppvt;
TYPE_NAME(struct_type) = type_decl; bfields[3].location = BUILTINS_LOCATION;
go_preserve_from_gc(type_decl);
rest_of_decl_compilation(type_decl, 1, 0);
type_tree = build_pointer_type(struct_type); Btype *bt = gogo->backend()->struct_type(bfields);
go_preserve_from_gc(type_tree); bt = gogo->backend()->named_type("__go_map", bt, BUILTINS_LOCATION);
backend_map_type = gogo->backend()->pointer_type(bt);
} }
return type_to_tree(backend_map_type);
return type_tree;
} }
// Initialize a map. // Initialize a map.
...@@ -5354,19 +5330,17 @@ Channel_type::do_check_make_expression(Expression_list* args, ...@@ -5354,19 +5330,17 @@ Channel_type::do_check_make_expression(Expression_list* args,
// libgo/runtime/channel.h. // libgo/runtime/channel.h.
tree tree
Channel_type::do_get_tree(Gogo*) Channel_type::do_get_tree(Gogo* gogo)
{ {
static tree type_tree; static Btype* backend_channel_type;
if (type_tree == NULL_TREE) if (backend_channel_type == NULL)
{ {
tree ret = make_node(RECORD_TYPE); std::vector<Backend::Btyped_identifier> bfields;
TYPE_NAME(ret) = get_identifier("__go_channel"); Btype* bt = gogo->backend()->struct_type(bfields);
TYPE_STUB_DECL(ret) = build_decl(BUILTINS_LOCATION, TYPE_DECL, NULL_TREE, bt = gogo->backend()->named_type("__go_channel", bt, BUILTINS_LOCATION);
ret); backend_channel_type = gogo->backend()->pointer_type(bt);
type_tree = build_pointer_type(ret);
go_preserve_from_gc(type_tree);
} }
return type_tree; return type_to_tree(backend_channel_type);
} }
// Initialize a channel variable. // Initialize a channel variable.
...@@ -8433,7 +8407,7 @@ Forward_declaration_type::do_traverse(Traverse* traverse) ...@@ -8433,7 +8407,7 @@ Forward_declaration_type::do_traverse(Traverse* traverse)
return TRAVERSE_CONTINUE; return TRAVERSE_CONTINUE;
} }
// Get a tree for the type. // Get the backend representation for the type.
tree tree
Forward_declaration_type::do_get_tree(Gogo* gogo) Forward_declaration_type::do_get_tree(Gogo* gogo)
...@@ -8445,15 +8419,13 @@ Forward_declaration_type::do_get_tree(Gogo* gogo) ...@@ -8445,15 +8419,13 @@ Forward_declaration_type::do_get_tree(Gogo* gogo)
return error_mark_node; return error_mark_node;
// We represent an undefined type as a struct with no fields. That // We represent an undefined type as a struct with no fields. That
// should work fine for the middle-end, since the same case can // should work fine for the backend, since the same case can arise
// arise in C. // in C.
Named_object* no = this->named_object(); std::vector<Backend::Btyped_identifier> fields;
tree type_tree = make_node(RECORD_TYPE); Btype* bt = gogo->backend()->struct_type(fields);
tree id = no->get_id(gogo); bt = gogo->backend()->named_type(this->name(), bt,
tree decl = build_decl(no->location(), TYPE_DECL, id, type_tree); this->named_object()->location());
TYPE_NAME(type_tree) = decl; return type_to_tree(bt);
layout_type(type_tree);
return type_tree;
} }
// Build a type descriptor for a forwarded type. // Build a type descriptor for a forwarded type.
......
...@@ -1098,11 +1098,6 @@ class Type ...@@ -1098,11 +1098,6 @@ class Type
bool* is_method, bool* found_pointer_method, bool* is_method, bool* found_pointer_method,
std::string* ambig1, std::string* ambig2); std::string* ambig1, std::string* ambig2);
// Get a tree for a type without looking in the hash table for
// identical types.
tree
get_tree_without_hash(Gogo*);
// Get the backend representation for a type without looking in the // Get the backend representation for a type without looking in the
// hash table for identical types. // hash table for identical types.
Btype* Btype*
......
...@@ -74,6 +74,9 @@ struct __go_channel ...@@ -74,6 +74,9 @@ struct __go_channel
uint64_t data[]; uint64_t data[];
}; };
/* Try to link up with the structure generated by the frontend. */
typedef struct __go_channel __go_channel;
/* The mutex used to control access to the value pointed to by the /* The mutex used to control access to the value pointed to by the
__go_channel_select selected field. No additional mutexes may be __go_channel_select selected field. No additional mutexes may be
acquired while this mutex is held. */ acquired while this mutex is held. */
......
...@@ -21,11 +21,11 @@ __go_map_rehash (struct __go_map *map) ...@@ -21,11 +21,11 @@ __go_map_rehash (struct __go_map *map)
size_t key_offset; size_t key_offset;
size_t key_size; size_t key_size;
size_t (*hashfn) (const void *, size_t); size_t (*hashfn) (const void *, size_t);
size_t old_bucket_count; uintptr_t old_bucket_count;
void **old_buckets; void **old_buckets;
size_t new_bucket_count; uintptr_t new_bucket_count;
void **new_buckets; void **new_buckets;
size_t i; uintptr_t i;
descriptor = map->__descriptor; descriptor = map->__descriptor;
......
...@@ -18,6 +18,6 @@ __go_map_len (struct __go_map *map) ...@@ -18,6 +18,6 @@ __go_map_len (struct __go_map *map)
{ {
if (map == NULL) if (map == NULL)
return 0; return 0;
__go_assert (map->__element_count == (size_t) (int) map->__element_count); __go_assert (map->__element_count == (uintptr_t) (int) map->__element_count);
return map->__element_count; return map->__element_count;
} }
...@@ -34,7 +34,7 @@ __go_mapiternext (struct __go_hash_iter *it) ...@@ -34,7 +34,7 @@ __go_mapiternext (struct __go_hash_iter *it)
if (entry == NULL) if (entry == NULL)
{ {
const struct __go_map *map; const struct __go_map *map;
size_t bucket; uintptr_t bucket;
map = it->map; map = it->map;
bucket = it->bucket; bucket = it->bucket;
......
...@@ -73,8 +73,8 @@ static const unsigned long prime_list[] = /* 256 + 1 or 256 + 48 + 1 */ ...@@ -73,8 +73,8 @@ static const unsigned long prime_list[] = /* 256 + 1 or 256 + 48 + 1 */
/* Return the next number from PRIME_LIST >= N. */ /* Return the next number from PRIME_LIST >= N. */
unsigned long uintptr_t
__go_map_next_prime (unsigned long n) __go_map_next_prime (uintptr_t n)
{ {
size_t low; size_t low;
size_t high; size_t high;
......
/* map.h -- the map type for Go. /* map.h -- the map type for Go.
Copyright 2009, 2010 The Go Authors. All rights reserved. Copyright 2009 The Go Authors. All rights reserved.
Use of this source code is governed by a BSD-style Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file. */ license that can be found in the LICENSE file. */
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
#include "go-type.h" #include "go-type.h"
...@@ -38,10 +39,10 @@ struct __go_map ...@@ -38,10 +39,10 @@ struct __go_map
const struct __go_map_descriptor *__descriptor; const struct __go_map_descriptor *__descriptor;
/* The number of elements in the hash table. */ /* The number of elements in the hash table. */
size_t __element_count; uintptr_t __element_count;
/* The number of entries in the __buckets array. */ /* The number of entries in the __buckets array. */
size_t __bucket_count; uintptr_t __bucket_count;
/* Each bucket is a pointer to a linked list of map entries. */ /* Each bucket is a pointer to a linked list of map entries. */
void **__buckets; void **__buckets;
...@@ -64,13 +65,13 @@ struct __go_hash_iter ...@@ -64,13 +65,13 @@ struct __go_hash_iter
all the entries in the current bucket. */ all the entries in the current bucket. */
const void *next_entry; const void *next_entry;
/* The bucket index of the current and next entry. */ /* The bucket index of the current and next entry. */
size_t bucket; uintptr_t bucket;
}; };
extern struct __go_map *__go_new_map (const struct __go_map_descriptor *, extern struct __go_map *__go_new_map (const struct __go_map_descriptor *,
uintptr_t); uintptr_t);
extern unsigned long __go_map_next_prime (unsigned long); extern uintptr_t __go_map_next_prime (uintptr_t);
extern void *__go_map_index (struct __go_map *, const void *, _Bool); extern void *__go_map_index (struct __go_map *, const void *, _Bool);
......
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