Commit 7b31a84d by Ian Lance Taylor

compiler: Permit type B byte; type S []B; var v = S("x").

From-SVN: r183112
parent 319638ed
...@@ -3382,9 +3382,11 @@ Type_conversion_expression::do_lower(Gogo*, Named_object*, ...@@ -3382,9 +3382,11 @@ Type_conversion_expression::do_lower(Gogo*, Named_object*,
if (type->is_slice_type()) if (type->is_slice_type())
{ {
Type* element_type = type->array_type()->element_type()->forwarded(); Type* element_type = type->array_type()->element_type()->forwarded();
bool is_byte = element_type == Type::lookup_integer_type("uint8"); bool is_byte = (element_type->integer_type() != NULL
bool is_int = element_type == Type::lookup_integer_type("int"); && element_type->integer_type()->is_byte());
if (is_byte || is_int) bool is_rune = (element_type->integer_type() != NULL
&& element_type->integer_type()->is_rune());
if (is_byte || is_rune)
{ {
std::string s; std::string s;
if (val->string_constant_value(&s)) if (val->string_constant_value(&s))
...@@ -3690,8 +3692,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context) ...@@ -3690,8 +3692,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context)
tree len = a->length_tree(gogo, expr_tree); tree len = a->length_tree(gogo, expr_tree);
len = fold_convert_loc(this->location().gcc_location(), integer_type_node, len = fold_convert_loc(this->location().gcc_location(), integer_type_node,
len); len);
if (e->integer_type()->is_unsigned() if (e->integer_type()->is_byte())
&& e->integer_type()->bits() == 8)
{ {
static tree byte_array_to_string_fndecl; static tree byte_array_to_string_fndecl;
ret = Gogo::call_builtin(&byte_array_to_string_fndecl, ret = Gogo::call_builtin(&byte_array_to_string_fndecl,
...@@ -3706,7 +3707,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context) ...@@ -3706,7 +3707,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context)
} }
else else
{ {
go_assert(e == Type::lookup_integer_type("int")); go_assert(e->integer_type()->is_rune());
static tree int_array_to_string_fndecl; static tree int_array_to_string_fndecl;
ret = Gogo::call_builtin(&int_array_to_string_fndecl, ret = Gogo::call_builtin(&int_array_to_string_fndecl,
this->location(), this->location(),
...@@ -3723,8 +3724,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context) ...@@ -3723,8 +3724,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context)
{ {
Type* e = type->array_type()->element_type()->forwarded(); Type* e = type->array_type()->element_type()->forwarded();
go_assert(e->integer_type() != NULL); go_assert(e->integer_type() != NULL);
if (e->integer_type()->is_unsigned() if (e->integer_type()->is_byte())
&& e->integer_type()->bits() == 8)
{ {
tree string_to_byte_array_fndecl = NULL_TREE; tree string_to_byte_array_fndecl = NULL_TREE;
ret = Gogo::call_builtin(&string_to_byte_array_fndecl, ret = Gogo::call_builtin(&string_to_byte_array_fndecl,
...@@ -3737,7 +3737,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context) ...@@ -3737,7 +3737,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context)
} }
else else
{ {
go_assert(e == Type::lookup_integer_type("int")); go_assert(e->integer_type()->is_rune());
tree string_to_int_array_fndecl = NULL_TREE; tree string_to_int_array_fndecl = NULL_TREE;
ret = Gogo::call_builtin(&string_to_int_array_fndecl, ret = Gogo::call_builtin(&string_to_int_array_fndecl,
this->location(), this->location(),
...@@ -8506,19 +8506,19 @@ Builtin_call_expression::do_check_types(Gogo*) ...@@ -8506,19 +8506,19 @@ Builtin_call_expression::do_check_types(Gogo*)
break; break;
} }
Type* e2;
if (arg2_type->is_slice_type()) if (arg2_type->is_slice_type())
e2 = arg2_type->array_type()->element_type(); {
Type* e2 = arg2_type->array_type()->element_type();
if (!Type::are_identical(e1, e2, true, NULL))
this->report_error(_("element types must be the same"));
}
else if (arg2_type->is_string_type()) else if (arg2_type->is_string_type())
e2 = Type::lookup_integer_type("uint8");
else
{ {
this->report_error(_("right argument must be a slice or a string")); if (e1->integer_type() == NULL || !e1->integer_type()->is_byte())
break; this->report_error(_("first argument must be []byte"));
} }
else
if (!Type::are_identical(e1, e2, true, NULL)) this->report_error(_("second argument must be slice or string"));
this->report_error(_("element types must be the same"));
} }
break; break;
...@@ -8542,7 +8542,7 @@ Builtin_call_expression::do_check_types(Gogo*) ...@@ -8542,7 +8542,7 @@ Builtin_call_expression::do_check_types(Gogo*)
{ {
const Array_type* at = args->front()->type()->array_type(); const Array_type* at = args->front()->type()->array_type();
const Type* e = at->element_type()->forwarded(); const Type* e = at->element_type()->forwarded();
if (e == Type::lookup_integer_type("uint8")) if (e->integer_type() != NULL && e->integer_type()->is_byte())
break; break;
} }
...@@ -9100,7 +9100,8 @@ Builtin_call_expression::do_get_tree(Translate_context* context) ...@@ -9100,7 +9100,8 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
tree arg2_len; tree arg2_len;
tree element_size; tree element_size;
if (arg2->type()->is_string_type() if (arg2->type()->is_string_type()
&& element_type == Type::lookup_integer_type("uint8")) && element_type->integer_type() != NULL
&& element_type->integer_type()->is_byte())
{ {
arg2_tree = save_expr(arg2_tree); arg2_tree = save_expr(arg2_tree);
arg2_val = String_type::bytes_tree(gogo, arg2_tree); arg2_val = String_type::bytes_tree(gogo, arg2_tree);
......
...@@ -88,10 +88,12 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int int_type_size, ...@@ -88,10 +88,12 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int int_type_size,
// to the same Named_object. // to the same Named_object.
Named_object* byte_type = this->declare_type("byte", loc); Named_object* byte_type = this->declare_type("byte", loc);
byte_type->set_type_value(uint8_type); byte_type->set_type_value(uint8_type);
uint8_type->integer_type()->set_is_byte();
// "rune" is an alias for "int". // "rune" is an alias for "int".
Named_object* rune_type = this->declare_type("rune", loc); Named_object* rune_type = this->declare_type("rune", loc);
rune_type->set_type_value(int_type); rune_type->set_type_value(int_type);
int_type->integer_type()->set_is_rune();
this->add_named_type(Type::make_integer_type("uintptr", true, this->add_named_type(Type::make_integer_type("uintptr", true,
pointer_size, pointer_size,
......
...@@ -767,7 +767,7 @@ Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason) ...@@ -767,7 +767,7 @@ Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason)
if (lhs->complex_type() != NULL && rhs->complex_type() != NULL) if (lhs->complex_type() != NULL && rhs->complex_type() != NULL)
return true; return true;
// An integer, or []byte, or []int, may be converted to a string. // An integer, or []byte, or []rune, may be converted to a string.
if (lhs->is_string_type()) if (lhs->is_string_type())
{ {
if (rhs->integer_type() != NULL) if (rhs->integer_type() != NULL)
...@@ -776,19 +776,18 @@ Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason) ...@@ -776,19 +776,18 @@ Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason)
{ {
const Type* e = rhs->array_type()->element_type()->forwarded(); const Type* e = rhs->array_type()->element_type()->forwarded();
if (e->integer_type() != NULL if (e->integer_type() != NULL
&& (e == Type::lookup_integer_type("uint8") && (e->integer_type()->is_byte()
|| e == Type::lookup_integer_type("int"))) || e->integer_type()->is_rune()))
return true; return true;
} }
} }
// A string may be converted to []byte or []int. // A string may be converted to []byte or []rune.
if (rhs->is_string_type() && lhs->is_slice_type()) if (rhs->is_string_type() && lhs->is_slice_type())
{ {
const Type* e = lhs->array_type()->element_type()->forwarded(); const Type* e = lhs->array_type()->element_type()->forwarded();
if (e->integer_type() != NULL if (e->integer_type() != NULL
&& (e == Type::lookup_integer_type("uint8") && (e->integer_type()->is_byte() || e->integer_type()->is_rune()))
|| e == Type::lookup_integer_type("int")))
return true; return true;
} }
......
...@@ -1386,7 +1386,27 @@ class Integer_type : public Type ...@@ -1386,7 +1386,27 @@ class Integer_type : public Type
bool bool
is_identical(const Integer_type* t) const; is_identical(const Integer_type* t) const;
protected: // Whether this is the type "byte" or another name for "byte".
bool
is_byte() const
{ return this->is_byte_; }
// Mark this as the "byte" type.
void
set_is_byte()
{ this->is_byte_ = true; }
// Whether this is the type "rune" or another name for "rune".
bool
is_rune() const
{ return this->is_rune_; }
// Mark this as the "rune" type.
void
set_is_rune()
{ this->is_rune_ = true; }
protected:
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*) const
{ return true; } { return true; }
...@@ -1410,8 +1430,8 @@ class Integer_type : public Type ...@@ -1410,8 +1430,8 @@ class Integer_type : public Type
Integer_type(bool is_abstract, bool is_unsigned, int bits, Integer_type(bool is_abstract, bool is_unsigned, int bits,
int runtime_type_kind) int runtime_type_kind)
: Type(TYPE_INTEGER), : Type(TYPE_INTEGER),
is_abstract_(is_abstract), is_unsigned_(is_unsigned), bits_(bits), is_abstract_(is_abstract), is_unsigned_(is_unsigned), is_byte_(false),
runtime_type_kind_(runtime_type_kind) is_rune_(false), bits_(bits), runtime_type_kind_(runtime_type_kind)
{ } { }
// Map names of integer types to the types themselves. // Map names of integer types to the types themselves.
...@@ -1422,6 +1442,10 @@ class Integer_type : public Type ...@@ -1422,6 +1442,10 @@ class Integer_type : public Type
bool is_abstract_; bool is_abstract_;
// True if this is an unsigned type. // True if this is an unsigned type.
bool is_unsigned_; bool is_unsigned_;
// True if this is the byte type.
bool is_byte_;
// True if this is the rune type.
bool is_rune_;
// The number of bits. // The number of bits.
int bits_; int bits_;
// The runtime type code used in the type descriptor for this type. // The runtime type code used in the type descriptor for this type.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment