diff options
Diffstat (limited to 'gcc/go/gofrontend/expressions.cc')
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 88 |
1 files changed, 87 insertions, 1 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 6414136..df1650a1 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -3440,6 +3440,9 @@ class Unsafe_type_conversion_expression : public Expression int do_traverse(Traverse* traverse); + bool + do_is_immutable() const; + Type* do_type() { return this->type_; } @@ -3480,6 +3483,27 @@ Unsafe_type_conversion_expression::do_traverse(Traverse* traverse) return TRAVERSE_CONTINUE; } +// Return whether an unsafe type conversion is immutable. + +bool +Unsafe_type_conversion_expression::do_is_immutable() const +{ + Type* type = this->type_; + Type* expr_type = this->expr_->type(); + + if (type->interface_type() != NULL + || expr_type->interface_type() != NULL) + return false; + + if (!this->expr_->is_immutable()) + return false; + + if (Type::are_convertible(type, expr_type, NULL)) + return true; + + return type->is_basic_type() && expr_type->is_basic_type(); +} + // Convert to backend representation. Bexpression* @@ -4115,8 +4139,11 @@ Unary_expression::do_get_backend(Translate_context* context) && !context->is_const()); } Bvariable* implicit = - gogo->backend()->implicit_variable(buf, btype, bexpr, copy_to_heap, + gogo->backend()->implicit_variable(buf, btype, true, copy_to_heap, false, 0); + gogo->backend()->implicit_variable_set_init(implicit, buf, btype, + true, copy_to_heap, false, + bexpr); bexpr = gogo->backend()->var_expression(implicit, loc); } else if ((this->expr_->is_composite_literal() @@ -13987,6 +14014,65 @@ Expression::make_type_descriptor(Type* type, Location location) return new Type_descriptor_expression(type, location); } +// An expression which evaluates to a pointer to the Garbage Collection symbol +// of a type. + +class GC_symbol_expression : public Expression +{ + public: + GC_symbol_expression(Type* type) + : Expression(EXPRESSION_GC_SYMBOL, Linemap::predeclared_location()), + type_(type) + {} + + protected: + Type* + do_type() + { return Type::make_pointer_type(Type::make_void_type()); } + + bool + do_is_immutable() const + { return true; } + + void + do_determine_type(const Type_context*) + { } + + Expression* + do_copy() + { return this; } + + Bexpression* + do_get_backend(Translate_context* context) + { return this->type_->gc_symbol_pointer(context->gogo()); } + + void + do_dump_expression(Ast_dump_context*) const; + + private: + // The type which this gc symbol describes. + Type* type_; +}; + +// Dump ast representation for a gc symbol expression. + +void +GC_symbol_expression::do_dump_expression( + Ast_dump_context* ast_dump_context) const +{ + ast_dump_context->ostream() << "gcdata("; + ast_dump_context->dump_type(this->type_); + ast_dump_context->ostream() << ")"; +} + +// Make a gc symbol expression. + +Expression* +Expression::make_gc_symbol(Type* type) +{ + return new GC_symbol_expression(type); +} + // An expression which evaluates to some characteristic of a type. // This is only used to initialize fields of a type descriptor. Using // a new expression class is slightly inefficient but gives us a good |