mirror of git://gcc.gnu.org/git/gcc.git
More uses of backend interface for types.
From-SVN: r173507
This commit is contained in:
parent
c81e79b590
commit
4e7e7a49b7
|
|
@ -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)
|
||||||
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,35 +884,6 @@ Type::get_tree(Gogo* gogo)
|
||||||
return t;
|
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
|
// Return the backend representation for a type without looking in the
|
||||||
// hash table for identical types. This is used for named types,
|
// hash table for identical types. This is used for named types,
|
||||||
// since a named type is never identical to any other type.
|
// since a named type is never identical to any other type.
|
||||||
|
|
@ -920,7 +891,26 @@ Type::get_tree_without_hash(Gogo* gogo)
|
||||||
Btype*
|
Btype*
|
||||||
Type::get_btype_without_hash(Gogo* gogo)
|
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.
|
// Return a tree representing a zero initialization for this 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
|
||||||
|
|
||||||
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,
|
||||||
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();
|
Type* pdt = Type::make_type_descriptor_ptr_type();
|
||||||
tree const_map_descriptor_type =
|
bfields[0].name = "__descriptor";
|
||||||
build_qualified_type(map_descriptor_type, TYPE_QUAL_CONST);
|
bfields[0].btype = tree_to_type(pdt->get_tree(gogo));
|
||||||
tree name = get_identifier("__descriptor");
|
bfields[0].location = BUILTINS_LOCATION;
|
||||||
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* uintptr_type = Type::lookup_integer_type("uintptr");
|
||||||
field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name, sizetype);
|
bfields[1].name = "__element_count";
|
||||||
DECL_CONTEXT(field) = struct_type;
|
bfields[1].btype = tree_to_type(uintptr_type->get_tree(gogo));
|
||||||
DECL_CHAIN(last_field) = field;
|
bfields[1].location = BUILTINS_LOCATION;
|
||||||
last_field = field;
|
|
||||||
|
|
||||||
name = get_identifier("__bucket_count");
|
bfields[2].name = "__bucket_count";
|
||||||
field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name, sizetype);
|
bfields[2].btype = bfields[1].btype;
|
||||||
DECL_CONTEXT(field) = struct_type;
|
bfields[2].location = BUILTINS_LOCATION;
|
||||||
DECL_CHAIN(last_field) = field;
|
|
||||||
last_field = field;
|
|
||||||
|
|
||||||
name = get_identifier("__buckets");
|
Btype* bvt = gogo->backend()->void_type();
|
||||||
field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name,
|
Btype* bpvt = gogo->backend()->pointer_type(bvt);
|
||||||
build_pointer_type(ptr_type_node));
|
Btype* bppvt = gogo->backend()->pointer_type(bpvt);
|
||||||
DECL_CONTEXT(field) = struct_type;
|
bfields[3].name = "__buckets";
|
||||||
DECL_CHAIN(last_field) = field;
|
bfields[3].btype = bppvt;
|
||||||
|
bfields[3].location = BUILTINS_LOCATION;
|
||||||
|
|
||||||
layout_type(struct_type);
|
Btype *bt = gogo->backend()->struct_type(bfields);
|
||||||
|
bt = gogo->backend()->named_type("__go_map", bt, BUILTINS_LOCATION);
|
||||||
// Give the struct a name for better debugging info.
|
backend_map_type = gogo->backend()->pointer_type(bt);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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,
|
||||||
// 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)
|
||||||
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)
|
||||||
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
|
||||||
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
|
||||||
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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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 */
|
||||||
|
|
||||||
/* 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;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
/* 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
|
||||||
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
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue