// When setting an interface to nil, we just set both fields to
// NULL.
if (rhs_type->is_nil_type())
- return lhs_type->get_init_tree(gogo, false);
+ {
+ Btype* lhs_btype = lhs_type->get_backend(gogo);
+ return expr_to_tree(gogo->backend()->zero_expression(lhs_btype));
+ }
// This should have been checked already.
go_assert(lhs_interface_type->implements_interface(rhs_type, NULL));
}
else
{
+ Gogo* gogo = context->gogo();
+ Btype* val_btype = type->val_type()->get_backend(gogo);
+ Bexpression* val_zero = gogo->backend()->zero_expression(val_btype);
return fold_build3(COND_EXPR, val_type_tree,
fold_build2(EQ_EXPR, boolean_type_node, valptr,
fold_convert(TREE_TYPE(valptr),
null_pointer_node)),
- type->val_type()->get_init_tree(context->gogo(),
- false),
+ expr_to_tree(val_zero),
build_fold_indirect_ref(valptr));
}
}
Gogo* gogo = context->gogo();
if (this->vals_ == NULL)
- return this->type_->get_init_tree(gogo, false);
+ {
+ Btype* btype = this->type_->get_backend(gogo);
+ return expr_to_tree(gogo->backend()->zero_expression(btype));
+ }
tree type_tree = type_to_tree(this->type_->get_backend(gogo));
if (type_tree == error_mark_node)
{
go_assert(pf != fields->end());
+ Btype* fbtype = pf->type()->get_backend(gogo);
+
tree val;
if (pv == this->vals_->end())
- val = pf->type()->get_init_tree(gogo, false);
+ val = expr_to_tree(gogo->backend()->zero_expression(fbtype));
else if (*pv == NULL)
{
- val = pf->type()->get_init_tree(gogo, false);
+ val = expr_to_tree(gogo->backend()->zero_expression(fbtype));
++pv;
}
else
constructor_elt* elt = VEC_quick_push(constructor_elt, values, NULL);
elt->index = size_int(i);
if (*pv == NULL)
- elt->value = element_type->get_init_tree(context->gogo(), false);
+ {
+ Gogo* gogo = context->gogo();
+ Btype* ebtype = element_type->get_backend(gogo);
+ Bexpression *zv = gogo->backend()->zero_expression(ebtype);
+ elt->value = expr_to_tree(zv);
+ }
else
{
tree value_tree = (*pv)->get_tree(context);
VEC(constructor_elt,gc)* vec = VEC_alloc(constructor_elt, gc, 1);
constructor_elt* elt = VEC_quick_push(constructor_elt, vec, NULL);
elt->index = size_int(0);
- elt->value = element_type->get_init_tree(context->gogo(), false);
+ Gogo* gogo = context->gogo();
+ Btype* btype = element_type->get_backend(gogo);
+ elt->value = expr_to_tree(gogo->backend()->zero_expression(btype));
values = build_constructor(constructor_type, vec);
if (TREE_CONSTANT(elt->value))
TREE_CONSTANT(values) = 1;
return this->btype_;
}
-// Return a tree representing a zero initialization for this type.
-
-tree
-Type::get_init_tree(Gogo* gogo, bool is_clear)
-{
- tree type_tree = type_to_tree(this->get_backend(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
// this.
do_get_backend(Gogo* gogo)
{ return gogo->backend()->error_type(); }
- tree
- do_get_init_tree(Gogo*, tree, bool)
- { return error_mark_node; }
-
Expression*
do_type_descriptor(Gogo*, Named_type*)
{ return Expression::make_error(BUILTINS_LOCATION); }
do_get_backend(Gogo* gogo)
{ return gogo->backend()->void_type(); }
- tree
- do_get_init_tree(Gogo*, tree, bool)
- { go_unreachable(); }
-
Expression*
do_type_descriptor(Gogo*, Named_type*)
{ go_unreachable(); }
do_get_backend(Gogo* gogo)
{ return gogo->backend()->bool_type(); }
- tree
- do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
- { return is_clear ? NULL : fold_convert(type_tree, boolean_false_node); }
-
Expression*
do_type_descriptor(Gogo*, Named_type* name);
return gogo->backend()->integer_type(this->is_unsigned_, this->bits_);
}
-tree
-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
// named.
return gogo->backend()->float_type(this->bits_);
}
-tree
-Float_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
- if (is_clear)
- return NULL;
- REAL_VALUE_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.
Expression*
return gogo->backend()->complex_type(this->bits_);
}
-// Zero initializer.
-
-tree
-Complex_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
- if (is_clear)
- return NULL;
- REAL_VALUE_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
// named.
bytes_field, NULL_TREE);
}
-// We initialize a string to { NULL, 0 }.
-
-tree
-String_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
- if (is_clear)
- return NULL_TREE;
-
- go_assert(TREE_CODE(type_tree) == RECORD_TYPE);
-
- VEC(constructor_elt, gc)* init = VEC_alloc(constructor_elt, gc, 2);
-
- for (tree field = TYPE_FIELDS(type_tree);
- field != NULL_TREE;
- field = DECL_CHAIN(field))
- {
- constructor_elt* elt = VEC_quick_push(constructor_elt, init, NULL);
- elt->index = field;
- elt->value = fold_convert(TREE_TYPE(field), size_zero_node);
- }
-
- tree ret = build_constructor(type_tree, init);
- TREE_CONSTANT(ret) = 1;
- return ret;
-}
-
// The type descriptor for the string type.
Expression*
do_get_backend(Gogo*)
{ go_unreachable(); }
- tree
- do_get_init_tree(Gogo*, tree, bool)
- { go_unreachable(); }
-
Expression*
do_type_descriptor(Gogo*, Named_type*)
{ go_unreachable(); }
}
}
-// Functions are initialized to NULL.
-
-tree
-Function_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
- if (is_clear)
- return NULL;
- return fold_convert(type_tree, null_pointer_node);
-}
-
// The type of a function type descriptor.
Type*
return gogo->backend()->pointer_type(to_btype);
}
-// Initialize a pointer type.
-
-tree
-Pointer_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
- if (is_clear)
- return NULL;
- return fold_convert(type_tree, null_pointer_node);
-}
-
// The type of a pointer type descriptor.
Type*
do_get_backend(Gogo* gogo)
{ return gogo->backend()->pointer_type(gogo->backend()->void_type()); }
- tree
- do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
- { return is_clear ? NULL : fold_convert(type_tree, null_pointer_node); }
-
Expression*
do_type_descriptor(Gogo*, Named_type*)
{ go_unreachable(); }
return gogo->backend()->error_type();
}
- tree
- do_get_init_tree(Gogo*, tree, bool)
- {
- go_assert(saw_errors());
- return error_mark_node;
- }
-
Expression*
do_type_descriptor(Gogo*, Named_type*)
{
return gogo->backend()->struct_type(bfields);
}
-// Initialize struct fields.
-
-tree
-Struct_type::do_get_init_tree(Gogo* gogo, tree type_tree, bool is_clear)
-{
- if (this->fields_ == NULL || this->fields_->empty())
- {
- if (is_clear)
- return NULL;
- else
- {
- tree ret = build_constructor(type_tree,
- VEC_alloc(constructor_elt, gc, 0));
- TREE_CONSTANT(ret) = 1;
- return ret;
- }
- }
-
- bool is_constant = true;
- bool any_fields_set = false;
- VEC(constructor_elt,gc)* init = VEC_alloc(constructor_elt, gc,
- this->fields_->size());
-
- tree field = TYPE_FIELDS(type_tree);
- for (Struct_field_list::const_iterator p = this->fields_->begin();
- p != this->fields_->end();
- ++p, field = DECL_CHAIN(field))
- {
- tree value = p->type()->get_init_tree(gogo, is_clear);
- if (value == error_mark_node)
- return error_mark_node;
- go_assert(field != NULL_TREE);
- if (value != NULL)
- {
- constructor_elt* elt = VEC_quick_push(constructor_elt, init, NULL);
- elt->index = field;
- elt->value = value;
- any_fields_set = true;
- if (!TREE_CONSTANT(value))
- is_constant = false;
- }
- }
- go_assert(field == NULL_TREE);
-
- if (!any_fields_set)
- {
- go_assert(is_clear);
- VEC_free(constructor_elt, gc, init);
- return NULL;
- }
-
- tree ret = build_constructor(type_tree, init);
- if (is_constant)
- TREE_CONSTANT(ret) = 1;
- return ret;
-}
-
// The type of a struct type descriptor.
Type*
return tree_to_expr(this->get_length_tree(gogo));
}
-// Return an initializer for an array type.
-
-tree
-Array_type::do_get_init_tree(Gogo* gogo, tree type_tree, bool is_clear)
-{
- if (this->length_ == NULL)
- {
- // Open array.
-
- if (is_clear)
- return NULL;
-
- go_assert(TREE_CODE(type_tree) == RECORD_TYPE);
-
- VEC(constructor_elt,gc)* init = VEC_alloc(constructor_elt, gc, 3);
-
- for (tree field = TYPE_FIELDS(type_tree);
- field != NULL_TREE;
- field = DECL_CHAIN(field))
- {
- constructor_elt* elt = VEC_quick_push(constructor_elt, init,
- NULL);
- elt->index = field;
- elt->value = fold_convert(TREE_TYPE(field), size_zero_node);
- }
-
- tree ret = build_constructor(type_tree, init);
- TREE_CONSTANT(ret) = 1;
- return ret;
- }
- else
- {
- // Fixed array.
-
- tree value = this->element_type_->get_init_tree(gogo, is_clear);
- if (value == NULL)
- return NULL;
- if (value == error_mark_node)
- return error_mark_node;
-
- tree length_tree = this->get_length_tree(gogo);
- if (length_tree == error_mark_node)
- return error_mark_node;
-
- length_tree = fold_convert(sizetype, length_tree);
- tree range = build2(RANGE_EXPR, sizetype, size_zero_node,
- fold_build2(MINUS_EXPR, sizetype,
- length_tree, size_one_node));
- tree ret = build_constructor_single(type_tree, range, value);
- if (TREE_CONSTANT(value))
- TREE_CONSTANT(ret) = 1;
- return ret;
- }
-}
-
// Handle the builtin make function for a slice.
tree
return error_mark_node;
tree element_size_tree = TYPE_SIZE_UNIT(element_type_tree);
- tree value = this->element_type_->get_init_tree(gogo, true);
- if (value == error_mark_node)
- return error_mark_node;
-
// The first argument is the number of elements, the optional second
// argument is the capacity.
go_assert(args != NULL && args->size() >= 1 && args->size() <= 2);
tree space = context->gogo()->allocate_memory(this->element_type_,
size_tree, location);
- if (value != NULL_TREE)
- space = save_expr(space);
-
space = fold_convert(TREE_TYPE(values_field), space);
if (bad_index != NULL_TREE && bad_index != boolean_false_node)
space);
}
- tree constructor = gogo->slice_constructor(type_tree, space, length_tree,
- capacity_tree);
-
- if (value == NULL_TREE)
- {
- // The array contents are zero initialized.
- return constructor;
- }
-
- // The elements must be initialized.
-
- tree max = fold_build2_loc(location, MINUS_EXPR, TREE_TYPE(count_field),
- capacity_tree,
- fold_convert_loc(location, TREE_TYPE(count_field),
- integer_one_node));
-
- tree array_type = build_array_type(element_type_tree,
- build_index_type(max));
-
- tree value_pointer = fold_convert_loc(location,
- build_pointer_type(array_type),
- space);
-
- tree range = build2(RANGE_EXPR, sizetype, size_zero_node, max);
- tree space_init = build_constructor_single(array_type, range, value);
-
- return build2(COMPOUND_EXPR, TREE_TYPE(constructor),
- build2(MODIFY_EXPR, void_type_node,
- build_fold_indirect_ref(value_pointer),
- space_init),
- constructor);
+ return gogo->slice_constructor(type_tree, space, length_tree, capacity_tree);
}
// Return a tree for a pointer to the values in ARRAY.
return backend_map_type;
}
-// Initialize a map.
-
-tree
-Map_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
- if (is_clear)
- return NULL;
- return fold_convert(type_tree, null_pointer_node);
-}
-
// Return an expression for a newly allocated map.
tree
return backend_channel_type;
}
-// Initialize a channel variable.
-
-tree
-Channel_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
- if (is_clear)
- return NULL;
- return fold_convert(type_tree, null_pointer_node);
-}
-
// Handle the builtin function make for a channel.
tree
}
}
-// Initialization value.
-
-tree
-Interface_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
- if (is_clear)
- return NULL;
-
- VEC(constructor_elt,gc)* init = VEC_alloc(constructor_elt, gc, 2);
- for (tree field = TYPE_FIELDS(type_tree);
- field != NULL_TREE;
- field = DECL_CHAIN(field))
- {
- constructor_elt* elt = VEC_quick_push(constructor_elt, init, NULL);
- elt->index = field;
- elt->value = fold_convert(TREE_TYPE(field), null_pointer_node);
- }
-
- tree ret = build_constructor(type_tree, init);
- TREE_CONSTANT(ret) = 1;
- return ret;
-}
-
// The type of an interface type descriptor.
Type*
Btype*
get_backend(Gogo*);
- // Return a tree representing a zero initialization for this type.
- // This will be something like an INTEGER_CST or a CONSTRUCTOR. If
- // IS_CLEAR is true, then the memory is known to be zeroed; in that
- // case, this will return NULL if there is nothing to be done.
- 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,
virtual Btype*
do_get_backend(Gogo*) = 0;
- virtual tree
- do_get_init_tree(Gogo*, tree, bool) = 0;
-
virtual tree
do_make_expression_tree(Translate_context*, Expression_list*,
source_location);
Btype*
do_get_backend(Gogo*);
- tree
- do_get_init_tree(Gogo*, tree, bool);
-
Expression*
do_type_descriptor(Gogo*, Named_type*);
Btype*
do_get_backend(Gogo*);
- tree
- do_get_init_tree(Gogo*, tree, bool);
-
Expression*
do_type_descriptor(Gogo*, Named_type*);
Btype*
do_get_backend(Gogo*);
- tree
- do_get_init_tree(Gogo*, tree, bool);
-
Expression*
do_type_descriptor(Gogo*, Named_type*);
Btype*
do_get_backend(Gogo*);
- tree
- do_get_init_tree(Gogo* gogo, tree, bool);
-
Expression*
do_type_descriptor(Gogo*, Named_type*);
Btype*
do_get_backend(Gogo*);
- tree
- do_get_init_tree(Gogo*, tree, bool);
-
Expression*
do_type_descriptor(Gogo*, Named_type*);
Btype*
do_get_backend(Gogo*);
- tree
- do_get_init_tree(Gogo*, tree, bool);
-
Expression*
do_type_descriptor(Gogo*, Named_type*);
Btype*
do_get_backend(Gogo*);
- tree
- do_get_init_tree(Gogo*, tree, bool);
-
Expression*
do_type_descriptor(Gogo*, Named_type*);
Btype*
do_get_backend(Gogo*);
- tree
- do_get_init_tree(Gogo*, tree, bool);
-
tree
do_make_expression_tree(Translate_context*, Expression_list*,
source_location);
Btype*
do_get_backend(Gogo*);
- tree
- do_get_init_tree(Gogo*, tree, bool);
-
tree
do_make_expression_tree(Translate_context*, Expression_list*,
source_location);
Btype*
do_get_backend(Gogo*);
- tree
- do_get_init_tree(Gogo*, tree, bool);
-
tree
do_make_expression_tree(Translate_context*, Expression_list*,
source_location);
Btype*
do_get_backend(Gogo*);
- tree
- do_get_init_tree(Gogo* gogo, tree, bool);
-
Expression*
do_type_descriptor(Gogo*, Named_type*);
Btype*
do_get_backend(Gogo*);
- tree
- 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,
source_location location)
Btype*
do_get_backend(Gogo* gogo);
- tree
- 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,
source_location location)