@@ -787,21 +787,15 @@
return this->tree_;
}
-// Store an incomplete type tree during construction.
-
-void
-Type::set_incomplete_type_tree(tree incomplete)
-{
- gcc_assert(this->tree_ == NULL);
- this->tree_ = incomplete;
-}
-
// Return a tree representing a zero initialization for this type.
tree
Type::get_init_tree(Gogo* gogo, bool is_clear)
{
- return this->do_init_tree(gogo, is_clear);
+ tree type_tree = this->get_tree(gogo);
+ if (type_tree == error_mark_node)
+ return error_mark_node;
+ return this->do_get_init_tree(gogo, type_tree, is_clear);
}
// Any type which supports the builtin make function must implement
@@ -921,7 +915,7 @@
{ return error_mark_node; }
tree
- do_init_tree(Gogo*, bool)
+ do_get_init_tree(Gogo*, tree, bool)
{ return error_mark_node; }
void
@@ -959,7 +953,7 @@
{ return void_type_node; }
tree
- do_init_tree(Gogo*, bool)
+ do_get_init_tree(Gogo*, tree, bool)
{ gcc_unreachable(); }
void
@@ -997,8 +991,8 @@
{ return boolean_type_node; }
tree
- do_init_tree(Gogo*, bool is_clear)
- { return is_clear ? NULL : boolean_false_node; }
+ do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
+ { return is_clear ? NULL : fold_convert(type_tree, boolean_false_node); }
void
do_type_descriptor_decl(Gogo* gogo, Named_type* name, tree* pdecl);
@@ -1167,9 +1161,9 @@
}
tree
-Integer_type::do_init_tree(Gogo* gogo, bool is_clear)
-{
- return is_clear ? NULL : build_int_cst(this->get_tree(gogo), 0);
+Integer_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
+{
+ return is_clear ? NULL : build_int_cst(type_tree, 0);
}
// The type descriptor for an integer type. Integer types are always
@@ -1321,14 +1315,13 @@
}
tree
-Float_type::do_init_tree(Gogo* gogo, bool is_clear)
+Float_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
{
if (is_clear)
return NULL;
- tree type = this->get_tree(gogo);
REAL_VALUE_TYPE r;
- real_from_integer(&r, TYPE_MODE(type), 0, 0, 0);
- return build_real(type, r);
+ real_from_integer(&r, TYPE_MODE(type_tree), 0, 0, 0);
+ return build_real(type_tree, r);
}
// The type descriptor for a float type. Float types are always named.
@@ -1481,15 +1474,14 @@
// Zero initializer.
tree
-Complex_type::do_init_tree(Gogo* gogo, bool is_clear)
+Complex_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
{
if (is_clear)
return NULL;
- tree type = this->get_tree(gogo);
REAL_VALUE_TYPE r;
- real_from_integer(&r, TYPE_MODE(TREE_TYPE(type)), 0, 0, 0);
- return build_complex(type, build_real(TREE_TYPE(type), r),
- build_real(TREE_TYPE(type), r));
+ real_from_integer(&r, TYPE_MODE(TREE_TYPE(type_tree)), 0, 0, 0);
+ return build_complex(type_tree, build_real(TREE_TYPE(type_tree), r),
+ build_real(TREE_TYPE(type_tree), r));
}
// The type descriptor for a complex type. Complex types are always
@@ -1594,12 +1586,11 @@
// We initialize a string to { NULL, 0 }.
tree
-String_type::do_init_tree(Gogo* gogo, bool is_clear)
+String_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
{
if (is_clear)
return NULL_TREE;
- tree type_tree = this->get_tree(gogo);
gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
VEC(constructor_elt, gc)* init = VEC_alloc(constructor_elt, gc, 2);
@@ -1700,7 +1691,7 @@
{ gcc_unreachable(); }
tree
- do_init_tree(Gogo*, bool)
+ do_get_init_tree(Gogo*, tree, bool)
{ gcc_unreachable(); }
void
@@ -1979,15 +1970,6 @@
tree
Function_type::do_get_tree(Gogo* gogo)
{
- // A function type can refer to itself indirectly, as in
- // type F func() F
- // A Go function type is represented as a pointer to a GENERIC
- // function. Create a pointer node now and fill it in later.
- tree ret = make_node(POINTER_TYPE);
- SET_TYPE_MODE(ret, ptr_mode);
- layout_type(ret);
- this->set_incomplete_type_tree(ret);
-
tree args = NULL_TREE;
tree* pp = &args;
@@ -2060,35 +2042,20 @@
if (result == error_mark_node)
return error_mark_node;
- // A function type whose return type is the function type itself can
- // not be handled in GENERIC. Such a type can not be written in C,
- // but in Go it looks like "type F func() F". We turn this special
- // case into a function which returns a generic pointer.
- if (result == ret)
- result = ptr_type_node;
-
tree fntype = build_function_type(result, args);
if (fntype == error_mark_node)
return fntype;
- TREE_TYPE(ret) = fntype;
- TYPE_POINTER_TO(fntype) = ret;
- if (TYPE_STRUCTURAL_EQUALITY_P(fntype))
- SET_TYPE_STRUCTURAL_EQUALITY(ret);
-
- return ret;
+ return build_pointer_type(fntype);
}
// Functions are initialized to NULL.
tree
-Function_type::do_init_tree(Gogo* gogo, bool is_clear)
+Function_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
{
if (is_clear)
return NULL;
- tree type_tree = this->get_tree(gogo);
- if (type_tree == error_mark_node)
- return error_mark_node;
return fold_convert(type_tree, null_pointer_node);
}
@@ -2411,13 +2378,10 @@
// Initialize a pointer type.
tree
-Pointer_type::do_init_tree(Gogo* gogo, bool is_clear)
+Pointer_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
{
if (is_clear)
return NULL;
- tree type_tree = this->get_tree(gogo);
- if (type_tree == error_mark_node)
- return error_mark_node;
return fold_convert(type_tree, null_pointer_node);
}
@@ -2513,8 +2477,8 @@
{ return ptr_type_node; }
tree
- do_init_tree(Gogo*, bool is_clear)
- { return is_clear ? NULL : null_pointer_node; }
+ do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
+ { return is_clear ? NULL : fold_convert(type_tree, null_pointer_node); }
void
do_type_descriptor_decl(Gogo*, Named_type*, tree*)
@@ -2560,7 +2524,7 @@
do_get_tree(Gogo*);
tree
- do_init_tree(Gogo*, bool)
+ do_get_init_tree(Gogo*, tree, bool)
{ gcc_unreachable(); }
void
@@ -3019,11 +2983,16 @@
Struct_type::do_get_tree(Gogo* gogo)
{
tree type = make_node(RECORD_TYPE);
- this->set_incomplete_type_tree(type);
-
+ return this->fill_in_tree(gogo, type);
+}
+
+// Fill in the fields for a struct type.
+
+tree
+Struct_type::fill_in_tree(Gogo* gogo, tree type)
+{
tree field_trees = NULL_TREE;
tree* pp = &field_trees;
- gcc_assert(this->fields_ != NULL);
for (Struct_field_list::const_iterator p = this->fields_->begin();
p != this->fields_->end();
++p)
@@ -3050,12 +3019,8 @@
// Initialize struct fields.
tree
-Struct_type::do_init_tree(Gogo* gogo, bool is_clear)
-{
- tree type_tree = this->get_tree(gogo);
- if (type_tree == error_mark_node)
- return error_mark_node;
-
+Struct_type::do_get_init_tree(Gogo* gogo, tree type_tree, bool is_clear)
+{
if (this->fields_ == NULL || this->fields_->empty())
{
if (is_clear)
@@ -3550,7 +3515,12 @@
tree
Array_type::do_get_tree(Gogo* gogo)
{
- if (this->length_ != NULL)
+ if (this->length_ == NULL)
+ {
+ tree struct_type = gogo->slice_type_tree(void_type_node);
+ return this->fill_in_tree(gogo, struct_type);
+ }
+ else
{
tree element_type_tree = this->element_type_->get_tree(gogo);
tree length_tree = this->get_length_tree(gogo);
@@ -3568,48 +3538,47 @@
return build_array_type(element_type_tree, index_type);
}
- else
- {
- // Two different slices of the same element type are really the
- // same type. In order to make that valid at the tree level, we
- // make sure to return the same struct.
- std::pair<Type*, tree> val(this->element_type_, NULL);
- std::pair<Array_trees::iterator, bool> ins =
- Array_type::array_trees.insert(val);
- if (!ins.second)
- {
- // We've already created a tree type for a slice with this
- // element type.
- gcc_assert(ins.first->second != NULL_TREE);
- return ins.first->second;
- }
-
- // A slice type can be recursive, as in "type T []T". Avoid
- // infinite recursion by creating the struct first, and then
- // filling in the element type.
- tree struct_type = gogo->slice_type_tree(void_type_node);
- this->set_incomplete_type_tree(struct_type);
- ins.first->second = struct_type;
-
- tree element_type_tree = this->element_type_->get_tree(gogo);
-
- tree field = TYPE_FIELDS(struct_type);
- gcc_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__values") == 0);
- gcc_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;
- }
+}
+
+// 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)
+{
+ gcc_assert(this->length_ == NULL);
+
+ // Two different slices of the same element type are really the same
+ // type. In order to make that valid at the tree level, we make
+ // sure to return the same struct.
+ std::pair<Type*, tree> val(this->element_type_, NULL);
+ std::pair<Array_trees::iterator, bool> ins =
+ Array_type::array_trees.insert(val);
+ if (!ins.second)
+ {
+ // We've already created a tree type for a slice with this
+ // element type.
+ gcc_assert(ins.first->second != NULL_TREE);
+ return ins.first->second;
+ }
+
+ ins.first->second = struct_type;
+
+ tree element_type_tree = this->element_type_->get_tree(gogo);
+ tree field = TYPE_FIELDS(struct_type);
+ gcc_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__values") == 0);
+ gcc_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
-Array_type::do_init_tree(Gogo* gogo, bool is_clear)
-{
- tree type_tree = this->get_tree(gogo);
-
+Array_type::do_get_init_tree(Gogo* gogo, tree type_tree, bool is_clear)
+{
if (this->length_ == NULL)
{
// Open array.
@@ -4170,11 +4139,11 @@
// Initialize a map.
tree
-Map_type::do_init_tree(Gogo* gogo, bool is_clear)
+Map_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
{
if (is_clear)
return NULL;
- return fold_convert(this->get_tree(gogo), null_pointer_node);
+ return fold_convert(type_tree, null_pointer_node);
}
// Return an expression for a newly allocated map.
@@ -4344,11 +4313,11 @@
// Initialize a channel variable.
tree
-Channel_type::do_init_tree(Gogo* gogo, bool is_clear)
+Channel_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
{
if (is_clear)
return NULL;
- return fold_convert(this->get_tree(gogo), null_pointer_node);
+ return fold_convert(type_tree, null_pointer_node);
}
// Handle the builtin function make for a channel.
@@ -4844,14 +4813,13 @@
tree
Interface_type::do_get_tree(Gogo* gogo)
{
- tree dtype = gogo->type_descriptor_type_tree();
- dtype = build_pointer_type(build_qualified_type(dtype, TYPE_QUAL_CONST));
-
if (this->methods_ == NULL)
{
// At the tree level, use the same type for all empty
// interfaces. This lets us assign them to each other directly
// without triggering GIMPLE type errors.
+ tree dtype = gogo->type_descriptor_type_tree();
+ dtype = build_pointer_type(build_qualified_type(dtype, TYPE_QUAL_CONST));
static tree empty_interface;
return Gogo::builtin_struct(&empty_interface, "__go_empty_interface",
NULL_TREE, 2,
@@ -4861,46 +4829,31 @@
ptr_type_node);
}
- // Interface types can have methods which refer to the interface
- // type itself, so build the type first and then the method table.
- tree ret = make_node(RECORD_TYPE);
-
- tree field_trees = NULL_TREE;
- tree* pp = &field_trees;
-
- // Create the pointer to the method table but don't fill it in yet.
- tree mtype = make_node(POINTER_TYPE);
- SET_TYPE_MODE(mtype, ptr_mode);
- layout_type(mtype);
-
- tree name_tree = get_identifier("__methods");
- tree field = build_decl(this->location_, FIELD_DECL, name_tree, mtype);
- DECL_CONTEXT(field) = ret;
- *pp = field;
- pp = &TREE_CHAIN(field);
-
- name_tree = get_identifier("__object");
- field = build_decl(this->location_, FIELD_DECL, name_tree, ptr_type_node);
- DECL_CONTEXT(field) = ret;
- *pp = field;
-
- TYPE_FIELDS(ret) = field_trees;
-
- layout_type(ret);
-
- this->set_incomplete_type_tree(ret);
+ return this->fill_in_tree(gogo, make_node(RECORD_TYPE));
+}
+
+// Fill in the tree for an interface type. This is used for named
+// interface types.
+
+tree
+Interface_type::fill_in_tree(Gogo* gogo, tree type)
+{
+ gcc_assert(this->methods_ != NULL);
// Build the type of the table of methods.
+
tree method_table = make_node(RECORD_TYPE);
// The first field is a pointer to the type descriptor.
- name_tree = get_identifier("__type_descriptor");
- field = build_decl(this->location_, FIELD_DECL, name_tree, dtype);
+ tree name_tree = get_identifier("__type_descriptor");
+ tree dtype = gogo->type_descriptor_type_tree();
+ dtype = build_pointer_type(build_qualified_type(dtype, TYPE_QUAL_CONST));
+ tree field = build_decl(this->location_, FIELD_DECL, name_tree, dtype);
DECL_CONTEXT(field) = method_table;
TYPE_FIELDS(method_table) = field;
std::string last_name = "";
- pp = &TREE_CHAIN(field);
+ tree* pp = &TREE_CHAIN(field);
for (Typed_identifier_list::const_iterator p = this->methods_->begin();
p != this->methods_->end();
++p)
@@ -4920,25 +4873,37 @@
}
layout_type(method_table);
- // Finish up the pointer to the method table.
- TREE_TYPE(mtype) = method_table;
- TYPE_POINTER_TO(method_table) = mtype;
- if (TYPE_STRUCTURAL_EQUALITY_P(method_table))
- SET_TYPE_STRUCTURAL_EQUALITY(mtype);
-
- return ret;
+ tree mtype = build_pointer_type(method_table);
+
+ tree field_trees = NULL_TREE;
+ pp = &field_trees;
+
+ name_tree = get_identifier("__methods");
+ field = build_decl(this->location_, FIELD_DECL, name_tree, mtype);
+ DECL_CONTEXT(field) = type;
+ *pp = field;
+ pp = &TREE_CHAIN(field);
+
+ name_tree = get_identifier("__object");
+ field = build_decl(this->location_, FIELD_DECL, name_tree, ptr_type_node);
+ DECL_CONTEXT(field) = type;
+ *pp = field;
+
+ TYPE_FIELDS(type) = field_trees;
+
+ layout_type(type);
+
+ return type;
}
// Initialization value.
tree
-Interface_type::do_init_tree(Gogo* gogo, bool is_clear)
+Interface_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
{
if (is_clear)
return NULL;
- tree type_tree = this->get_tree(gogo);
-
VEC(constructor_elt,gc)* init = VEC_alloc(constructor_elt, gc, 2);
for (tree field = TYPE_FIELDS(type_tree);
field != NULL_TREE;
@@ -5705,32 +5670,127 @@
if (this->is_error_)
return error_mark_node;
- tree type_tree = this->type_->get_tree(gogo);
- if (type_tree != error_mark_node)
- {
- tree id = this->named_object_->get_id(gogo);
-
- // If we are looking at a struct, interface, function, channel
- // or map, we don't need to make a copy to hold the type. Doing
- // this makes it easier for the middle-end to notice when the
- // types refer to themselves.
- if (TYPE_NAME(type_tree) == NULL
- && (this->type_->struct_type() != NULL
- || this->type_->interface_type() != NULL
- || this->type_->function_type() != NULL
- || this->type_->channel_type() != NULL
- || this->type_->map_type() != NULL))
- ;
+ // Go permits types to refer to themselves in various ways. Break
+ // the recursion here.
+ tree t;
+ switch (this->type_->forwarded()->classification())
+ {
+ case TYPE_ERROR:
+ return error_mark_node;
+
+ case TYPE_VOID:
+ case TYPE_BOOLEAN:
+ case TYPE_INTEGER:
+ case TYPE_FLOAT:
+ case TYPE_COMPLEX:
+ case TYPE_STRING:
+ case TYPE_NIL:
+ // These types can not refer to themselves.
+ case TYPE_MAP:
+ case TYPE_CHANNEL:
+ // All maps and channels have the same type in GENERIC.
+ t = this->type_->get_tree(gogo);
+ if (t == error_mark_node)
+ return error_mark_node;
+ // Build a copy to set TYPE_NAME.
+ t = build_variant_type_copy(t);
+ break;
+
+ case TYPE_FUNCTION:
+ case TYPE_POINTER:
+ if (this->seen_)
+ {
+ // GENERIC can't handle a pointer type which points to
+ // itself. It goes into infinite loops when walking the
+ // types.
+ return ptr_type_node;
+ }
+ this->seen_ = true;
+ t = this->type_->get_tree(gogo);
+ this->seen_ = false;
+ if (t == error_mark_node)
+ return error_mark_node;
+ t = build_variant_type_copy(t);
+ break;
+
+ case TYPE_STRUCT:
+ if (this->named_tree_ != NULL_TREE)
+ return this->named_tree_;
+ t = make_node(RECORD_TYPE);
+ this->named_tree_ = t;
+ this->type_->struct_type()->fill_in_tree(gogo, t);
+ break;
+
+ case TYPE_ARRAY:
+ if (!this->is_open_array_type())
+ t = this->type_->get_tree(gogo);
else
{
- // Make a copy so that we can set TYPE_NAME.
- type_tree = build_variant_type_copy(type_tree);
+ 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);
}
-
- tree decl = build_decl(this->location_, TYPE_DECL, id, type_tree);
- TYPE_NAME(type_tree) = decl;
- }
- return type_tree;
+ if (t == error_mark_node)
+ return error_mark_node;
+ t = build_variant_type_copy(t);
+ break;
+
+ case TYPE_INTERFACE:
+ if (this->type_->interface_type()->is_empty())
+ {
+ t = this->type_->get_tree(gogo);
+ if (t == error_mark_node)
+ return error_mark_node;
+ t = build_variant_type_copy(t);
+ }
+ else
+ {
+ if (this->named_tree_ != NULL_TREE)
+ return this->named_tree_;
+ t = make_node(RECORD_TYPE);
+ this->named_tree_ = t;
+ t = this->type_->interface_type()->fill_in_tree(gogo, t);
+ }
+ break;
+
+ case TYPE_NAMED:
+ {
+ // When a named type T1 is defined as another named type T2,
+ // the definition must simply be "type T1 T2". If the
+ // definition of T2 may refer to T1, then we must simply
+ // return the type for T2 here. It's not precisely correct,
+ // but it's as close as we can get with GENERIC.
+ bool was_seen = this->seen_;
+ this->seen_ = true;
+ t = this->type_->get_tree(gogo);
+ this->seen_ = was_seen;
+ if (was_seen)
+ return t;
+ if (t == error_mark_node)
+ return error_mark_node;
+ t = build_variant_type_copy(t);
+ }
+ break;
+
+ case TYPE_FORWARD:
+ // An undefined forwarding type. Make sure the error is
+ // emitted.
+ this->type_->forward_declaration_type()->real_type();
+ return error_mark_node;
+
+ default:
+ case TYPE_SINK:
+ case TYPE_CALL_MULTIPLE_RESULT:
+ gcc_unreachable();
+ }
+
+ tree id = this->named_object_->get_id(gogo);
+ tree decl = build_decl(this->location_, TYPE_DECL, id, t);
+ TYPE_NAME(t) = decl;
+
+ return t;
}
// Type descriptor decl.
@@ -799,6 +799,12 @@
tree
get_init_tree(Gogo*, bool is_clear);
+ // Like get_init_tree, but passing in the type to use for the
+ // initializer.
+ tree
+ get_typed_init_tree(Gogo* gogo, tree type_tree, bool is_clear)
+ { return this->do_get_init_tree(gogo, type_tree, is_clear); }
+
// Return a tree for a make expression applied to this type.
tree
make_expression_tree(Translate_context* context, Expression_list* args,
@@ -858,7 +864,7 @@
do_get_tree(Gogo*) = 0;
virtual tree
- do_init_tree(Gogo*, bool) = 0;
+ do_get_init_tree(Gogo*, tree, bool) = 0;
virtual tree
do_make_expression_tree(Translate_context*, Expression_list*,
@@ -911,10 +917,6 @@
append_mangled_name(const Type* type, Gogo* gogo, std::string* ret) const
{ type->do_mangled_name(gogo, ret); }
- // Store the type tree during construction.
- void
- set_incomplete_type_tree(tree);
-
// Incorporate a string into a hash code.
static unsigned int
hash_string(const std::string&, unsigned int);
@@ -1232,7 +1234,7 @@
do_get_tree(Gogo*);
tree
- do_init_tree(Gogo*, bool);
+ do_get_init_tree(Gogo*, tree, bool);
void
do_type_descriptor_decl(Gogo*, Named_type*, tree*);
@@ -1308,7 +1310,7 @@
do_get_tree(Gogo*);
tree
- do_init_tree(Gogo*, bool);
+ do_get_init_tree(Gogo*, tree, bool);
void
do_type_descriptor_decl(Gogo*, Named_type*, tree*);
@@ -1380,7 +1382,7 @@
do_get_tree(Gogo*);
tree
- do_init_tree(Gogo*, bool);
+ do_get_init_tree(Gogo*, tree, bool);
void
do_type_descriptor_decl(Gogo*, Named_type*, tree*);
@@ -1436,7 +1438,7 @@
do_get_tree(Gogo*);
tree
- do_init_tree(Gogo* gogo, bool);
+ do_get_init_tree(Gogo* gogo, tree, bool);
void
do_type_descriptor_decl(Gogo*, Named_type*, tree*);
@@ -1549,7 +1551,7 @@
do_get_tree(Gogo*);
tree
- do_init_tree(Gogo*, bool);
+ do_get_init_tree(Gogo*, tree, bool);
void
do_type_descriptor_decl(Gogo*, Named_type*, tree*);
@@ -1616,7 +1618,7 @@
do_get_tree(Gogo*);
tree
- do_init_tree(Gogo*, bool);
+ do_get_init_tree(Gogo*, tree, bool);
void
do_type_descriptor_decl(Gogo*, Named_type*, tree*);
@@ -1850,6 +1852,10 @@
static Struct_type*
do_import(Import*);
+ // Fill in the fields for a named struct type.
+ tree
+ fill_in_tree(Gogo*, tree);
+
protected:
int
do_traverse(Traverse*);
@@ -1867,7 +1873,7 @@
do_get_tree(Gogo*);
tree
- do_init_tree(Gogo*, bool);
+ do_get_init_tree(Gogo*, tree, bool);
void
do_type_descriptor_decl(Gogo*, Named_type*, tree*);
@@ -1939,6 +1945,10 @@
static Array_type*
do_import(Import*);
+ // Fill in the fields for a named slice type.
+ tree
+ fill_in_tree(Gogo*, tree);
+
protected:
int
do_traverse(Traverse* traverse);
@@ -1962,7 +1972,7 @@
do_get_tree(Gogo*);
tree
- do_init_tree(Gogo*, bool);
+ do_get_init_tree(Gogo*, tree, bool);
tree
do_make_expression_tree(Translate_context*, Expression_list*,
@@ -2054,7 +2064,7 @@
do_get_tree(Gogo*);
tree
- do_init_tree(Gogo*, bool);
+ do_get_init_tree(Gogo*, tree, bool);
tree
do_make_expression_tree(Translate_context*, Expression_list*,
@@ -2135,7 +2145,7 @@
do_get_tree(Gogo*);
tree
- do_init_tree(Gogo*, bool);
+ do_get_init_tree(Gogo*, tree, bool);
tree
do_make_expression_tree(Translate_context*, Expression_list*,
@@ -2226,6 +2236,10 @@
static Interface_type*
do_import(Import*);
+ // Fill in the fields for a named interface type.
+ tree
+ fill_in_tree(Gogo*, tree);
+
protected:
int
do_traverse(Traverse*);
@@ -2241,7 +2255,7 @@
do_get_tree(Gogo*);
tree
- do_init_tree(Gogo* gogo, bool);
+ do_get_init_tree(Gogo* gogo, tree, bool);
void
do_type_descriptor_decl(Gogo*, Named_type*, tree*);
@@ -2277,7 +2291,8 @@
named_object_(named_object), in_function_(NULL), type_(type),
local_methods_(NULL), all_methods_(NULL),
interface_method_tables_(NULL), pointer_interface_method_tables_(NULL),
- location_(location), is_visible_(true), is_error_(false), seen_(false)
+ location_(location), named_tree_(NULL), is_visible_(true),
+ is_error_(false), seen_(false)
{ }
// Return the associated Named_object. This holds the actual name.
@@ -2444,8 +2459,8 @@
do_get_tree(Gogo*);
tree
- do_init_tree(Gogo* gogo, bool is_clear)
- { return this->type_->get_init_tree(gogo, is_clear); }
+ do_get_init_tree(Gogo* gogo, tree type_tree, bool is_clear)
+ { return this->type_->get_typed_init_tree(gogo, type_tree, is_clear); }
tree
do_make_expression_tree(Translate_context* context, Expression_list* args,
@@ -2492,6 +2507,9 @@
Interface_method_tables* pointer_interface_method_tables_;
// The location where this type was defined.
source_location location_;
+ // The tree for this type while converting to GENERIC. This is used
+ // to avoid endless recursion when a named type refers to itself.
+ tree named_tree_;
// Whether this type is visible. This is false if this type was
// created because it was referenced by an imported object, but the
// type itself was not exported. This will always be true for types
@@ -2567,8 +2585,8 @@
do_get_tree(Gogo* gogo);
tree
- do_init_tree(Gogo* gogo, bool is_clear)
- { return this->base()->get_init_tree(gogo, is_clear); }
+ do_get_init_tree(Gogo* gogo, tree type_tree, bool is_clear)
+ { return this->base()->get_typed_init_tree(gogo, type_tree, is_clear); }
tree
do_make_expression_tree(Translate_context* context, Expression_list* args,