More uses of backend interface for types.

From-SVN: r173507
This commit is contained in:
Ian Lance Taylor 2011-05-06 20:06:29 +00:00
parent c81e79b590
commit 4e7e7a49b7
8 changed files with 88 additions and 117 deletions

View File

@ -845,7 +845,7 @@ Type::get_tree(Gogo* gogo)
if (this->forward_declaration_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())
return error_mark_node;
@ -865,7 +865,7 @@ Type::get_tree(Gogo* gogo)
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)
ins.first->second = t;
@ -884,35 +884,6 @@ Type::get_tree(Gogo* gogo)
return t;
}
// Return a tree for a type without looking in the hash table for
// identical types. This is used for named types, since there is no
// point to looking in the hash table for them.
tree
Type::get_tree_without_hash(Gogo* gogo)
{
if (this->tree_ == NULL_TREE)
{
tree t = this->do_get_tree(gogo);
// For a recursive function or pointer type, we will temporarily
// return a circular pointer type during the recursion. We
// don't want to record that for a forwarding type, as it may
// confuse us later.
if (this->forward_declaration_type() != NULL
&& gogo->backend()->is_circular_pointer_type(tree_to_type(t)))
return t;
if (gogo == NULL || !gogo->named_types_are_converted())
return t;
this->tree_ = t;
go_preserve_from_gc(t);
}
return 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.
@ -920,7 +891,26 @@ Type::get_tree_without_hash(Gogo* gogo)
Btype*
Type::get_btype_without_hash(Gogo* gogo)
{
return tree_to_type(this->get_tree_without_hash(gogo));
if (this->tree_ == NULL_TREE)
{
Btype* bt = tree_to_type(this->do_get_tree(gogo));
// For a recursive function or pointer type, we will temporarily
// return a circular pointer type during the recursion. We
// don't want to record that for a forwarding type, as it may
// confuse us later.
if (this->forward_declaration_type() != NULL
&& gogo->backend()->is_circular_pointer_type(bt))
return bt;
if (gogo == NULL || !gogo->named_types_are_converted())
return bt;
tree t = type_to_tree(bt);
this->tree_ = t;
}
return tree_to_type(this->tree_);
}
// Return a tree representing a zero initialization for this type.
@ -1596,8 +1586,8 @@ class Error_type : public Type
protected:
tree
do_get_tree(Gogo*)
{ return error_mark_node; }
do_get_tree(Gogo* gogo)
{ return type_to_tree(gogo->backend()->error_type()); }
tree
do_get_init_tree(Gogo*, tree, bool)
@ -3228,8 +3218,11 @@ class Nil_type : public Type
protected:
tree
do_get_tree(Gogo*)
{ return ptr_type_node; }
do_get_tree(Gogo* gogo)
{
Btype* bt = gogo->backend()->pointer_type(gogo->backend()->void_type());
return type_to_tree(bt);
}
tree
do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
@ -5064,61 +5057,44 @@ Map_type::do_check_make_expression(Expression_list* args,
return true;
}
// Get a tree for a map type. A map type is represented as a pointer
// to a struct. The struct is __go_map in libgo/map.h.
// Get the backend representation for a map type. A map type is
// represented as a pointer to a struct. The struct is __go_map in
// libgo/map.h.
tree
Map_type::do_get_tree(Gogo* gogo)
{
static tree type_tree;
if (type_tree == NULL_TREE)
static Btype* backend_map_type;
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;
Type* pdt = Type::make_type_descriptor_ptr_type();
bfields[0].name = "__descriptor";
bfields[0].btype = tree_to_type(pdt->get_tree(gogo));
bfields[0].location = BUILTINS_LOCATION;
name = get_identifier("__element_count");
field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name, sizetype);
DECL_CONTEXT(field) = struct_type;
DECL_CHAIN(last_field) = field;
last_field = field;
Type* uintptr_type = Type::lookup_integer_type("uintptr");
bfields[1].name = "__element_count";
bfields[1].btype = tree_to_type(uintptr_type->get_tree(gogo));
bfields[1].location = BUILTINS_LOCATION;
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;
bfields[2].name = "__bucket_count";
bfields[2].btype = bfields[1].btype;
bfields[2].location = BUILTINS_LOCATION;
name = get_identifier("__buckets");
field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name,
build_pointer_type(ptr_type_node));
DECL_CONTEXT(field) = struct_type;
DECL_CHAIN(last_field) = field;
Btype* bvt = gogo->backend()->void_type();
Btype* bpvt = gogo->backend()->pointer_type(bvt);
Btype* bppvt = gogo->backend()->pointer_type(bpvt);
bfields[3].name = "__buckets";
bfields[3].btype = bppvt;
bfields[3].location = BUILTINS_LOCATION;
layout_type(struct_type);
// Give the struct a name for better debugging info.
name = get_identifier("__go_map");
tree type_decl = build_decl(BUILTINS_LOCATION, TYPE_DECL, name,
struct_type);
DECL_ARTIFICIAL(type_decl) = 1;
TYPE_NAME(struct_type) = type_decl;
go_preserve_from_gc(type_decl);
rest_of_decl_compilation(type_decl, 1, 0);
type_tree = build_pointer_type(struct_type);
go_preserve_from_gc(type_tree);
Btype *bt = gogo->backend()->struct_type(bfields);
bt = gogo->backend()->named_type("__go_map", bt, BUILTINS_LOCATION);
backend_map_type = gogo->backend()->pointer_type(bt);
}
return type_tree;
return type_to_tree(backend_map_type);
}
// Initialize a map.
@ -5354,19 +5330,17 @@ Channel_type::do_check_make_expression(Expression_list* args,
// libgo/runtime/channel.h.
tree
Channel_type::do_get_tree(Gogo*)
Channel_type::do_get_tree(Gogo* gogo)
{
static tree type_tree;
if (type_tree == NULL_TREE)
static Btype* backend_channel_type;
if (backend_channel_type == NULL)
{
tree ret = make_node(RECORD_TYPE);
TYPE_NAME(ret) = get_identifier("__go_channel");
TYPE_STUB_DECL(ret) = build_decl(BUILTINS_LOCATION, TYPE_DECL, NULL_TREE,
ret);
type_tree = build_pointer_type(ret);
go_preserve_from_gc(type_tree);
std::vector<Backend::Btyped_identifier> bfields;
Btype* bt = gogo->backend()->struct_type(bfields);
bt = gogo->backend()->named_type("__go_channel", bt, BUILTINS_LOCATION);
backend_channel_type = gogo->backend()->pointer_type(bt);
}
return type_tree;
return type_to_tree(backend_channel_type);
}
// Initialize a channel variable.
@ -8433,7 +8407,7 @@ Forward_declaration_type::do_traverse(Traverse* traverse)
return TRAVERSE_CONTINUE;
}
// Get a tree for the type.
// Get the backend representation for the type.
tree
Forward_declaration_type::do_get_tree(Gogo* gogo)
@ -8445,15 +8419,13 @@ Forward_declaration_type::do_get_tree(Gogo* gogo)
return error_mark_node;
// We represent an undefined type as a struct with no fields. That
// should work fine for the middle-end, since the same case can
// arise in C.
Named_object* no = this->named_object();
tree type_tree = make_node(RECORD_TYPE);
tree id = no->get_id(gogo);
tree decl = build_decl(no->location(), TYPE_DECL, id, type_tree);
TYPE_NAME(type_tree) = decl;
layout_type(type_tree);
return type_tree;
// should work fine for the backend, since the same case can arise
// in C.
std::vector<Backend::Btyped_identifier> fields;
Btype* bt = gogo->backend()->struct_type(fields);
bt = gogo->backend()->named_type(this->name(), bt,
this->named_object()->location());
return type_to_tree(bt);
}
// Build a type descriptor for a forwarded type.

View File

@ -1098,11 +1098,6 @@ class Type
bool* is_method, bool* found_pointer_method,
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
// hash table for identical types.
Btype*

View File

@ -74,6 +74,9 @@ struct __go_channel
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
__go_channel_select selected field. No additional mutexes may be
acquired while this mutex is held. */

View File

@ -21,11 +21,11 @@ __go_map_rehash (struct __go_map *map)
size_t key_offset;
size_t key_size;
size_t (*hashfn) (const void *, size_t);
size_t old_bucket_count;
uintptr_t old_bucket_count;
void **old_buckets;
size_t new_bucket_count;
uintptr_t new_bucket_count;
void **new_buckets;
size_t i;
uintptr_t i;
descriptor = map->__descriptor;

View File

@ -18,6 +18,6 @@ __go_map_len (struct __go_map *map)
{
if (map == NULL)
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;
}

View File

@ -34,7 +34,7 @@ __go_mapiternext (struct __go_hash_iter *it)
if (entry == NULL)
{
const struct __go_map *map;
size_t bucket;
uintptr_t bucket;
map = it->map;
bucket = it->bucket;

View File

@ -73,8 +73,8 @@ static const unsigned long prime_list[] = /* 256 + 1 or 256 + 48 + 1 */
/* Return the next number from PRIME_LIST >= N. */
unsigned long
__go_map_next_prime (unsigned long n)
uintptr_t
__go_map_next_prime (uintptr_t n)
{
size_t low;
size_t high;

View File

@ -1,10 +1,11 @@
/* 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
license that can be found in the LICENSE file. */
#include <stddef.h>
#include <stdint.h>
#include "go-type.h"
@ -38,10 +39,10 @@ struct __go_map
const struct __go_map_descriptor *__descriptor;
/* The number of elements in the hash table. */
size_t __element_count;
uintptr_t __element_count;
/* 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. */
void **__buckets;
@ -64,13 +65,13 @@ struct __go_hash_iter
all the entries in the current bucket. */
const void *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 *,
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);