diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-01-11 23:43:46 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-01-11 23:43:46 +0000 |
commit | 7b31a84d76aaed7715210c6dc7d50dc2c47afd79 (patch) | |
tree | bacee98cbc87e04c247259edae85e2dc36a2e675 /gcc | |
parent | 319638ed5cd91621c8164eca42bd96bbd8139f02 (diff) | |
download | gcc-7b31a84d76aaed7715210c6dc7d50dc2c47afd79.zip gcc-7b31a84d76aaed7715210c6dc7d50dc2c47afd79.tar.gz gcc-7b31a84d76aaed7715210c6dc7d50dc2c47afd79.tar.bz2 |
compiler: Permit type B byte; type S []B; var v = S("x").
From-SVN: r183112
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 41 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 11 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.h | 30 |
4 files changed, 55 insertions, 29 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 7166a56..5e66645 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -3382,9 +3382,11 @@ Type_conversion_expression::do_lower(Gogo*, Named_object*, if (type->is_slice_type()) { Type* element_type = type->array_type()->element_type()->forwarded(); - bool is_byte = element_type == Type::lookup_integer_type("uint8"); - bool is_int = element_type == Type::lookup_integer_type("int"); - if (is_byte || is_int) + bool is_byte = (element_type->integer_type() != NULL + && element_type->integer_type()->is_byte()); + bool is_rune = (element_type->integer_type() != NULL + && element_type->integer_type()->is_rune()); + if (is_byte || is_rune) { std::string s; if (val->string_constant_value(&s)) @@ -3690,8 +3692,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context) tree len = a->length_tree(gogo, expr_tree); len = fold_convert_loc(this->location().gcc_location(), integer_type_node, len); - if (e->integer_type()->is_unsigned() - && e->integer_type()->bits() == 8) + if (e->integer_type()->is_byte()) { static tree 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) } else { - go_assert(e == Type::lookup_integer_type("int")); + go_assert(e->integer_type()->is_rune()); static tree int_array_to_string_fndecl; ret = Gogo::call_builtin(&int_array_to_string_fndecl, this->location(), @@ -3723,8 +3724,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context) { Type* e = type->array_type()->element_type()->forwarded(); go_assert(e->integer_type() != NULL); - if (e->integer_type()->is_unsigned() - && e->integer_type()->bits() == 8) + if (e->integer_type()->is_byte()) { tree string_to_byte_array_fndecl = NULL_TREE; ret = Gogo::call_builtin(&string_to_byte_array_fndecl, @@ -3737,7 +3737,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context) } else { - go_assert(e == Type::lookup_integer_type("int")); + go_assert(e->integer_type()->is_rune()); tree string_to_int_array_fndecl = NULL_TREE; ret = Gogo::call_builtin(&string_to_int_array_fndecl, this->location(), @@ -8506,19 +8506,19 @@ Builtin_call_expression::do_check_types(Gogo*) break; } - Type* e2; 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()) - e2 = Type::lookup_integer_type("uint8"); - else { - this->report_error(_("right argument must be a slice or a string")); - break; + if (e1->integer_type() == NULL || !e1->integer_type()->is_byte()) + this->report_error(_("first argument must be []byte")); } - - if (!Type::are_identical(e1, e2, true, NULL)) - this->report_error(_("element types must be the same")); + else + this->report_error(_("second argument must be slice or string")); } break; @@ -8542,7 +8542,7 @@ Builtin_call_expression::do_check_types(Gogo*) { const Array_type* at = args->front()->type()->array_type(); 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; } @@ -9100,7 +9100,8 @@ Builtin_call_expression::do_get_tree(Translate_context* context) tree arg2_len; tree element_size; 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_val = String_type::bytes_tree(gogo, arg2_tree); diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index f6f22d4..a5de175 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -88,10 +88,12 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int int_type_size, // to the same Named_object. Named_object* byte_type = this->declare_type("byte", loc); byte_type->set_type_value(uint8_type); + uint8_type->integer_type()->set_is_byte(); // "rune" is an alias for "int". Named_object* rune_type = this->declare_type("rune", loc); rune_type->set_type_value(int_type); + int_type->integer_type()->set_is_rune(); this->add_named_type(Type::make_integer_type("uintptr", true, pointer_size, diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index c8600ac..055bd67 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -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) 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 (rhs->integer_type() != NULL) @@ -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(); if (e->integer_type() != NULL - && (e == Type::lookup_integer_type("uint8") - || e == Type::lookup_integer_type("int"))) + && (e->integer_type()->is_byte() + || e->integer_type()->is_rune())) 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()) { const Type* e = lhs->array_type()->element_type()->forwarded(); if (e->integer_type() != NULL - && (e == Type::lookup_integer_type("uint8") - || e == Type::lookup_integer_type("int"))) + && (e->integer_type()->is_byte() || e->integer_type()->is_rune())) return true; } diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index 9de1b84..afb8a41 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -1386,7 +1386,27 @@ class Integer_type : public Type bool 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 do_compare_is_identity(Gogo*) const { return true; } @@ -1410,8 +1430,8 @@ class Integer_type : public Type Integer_type(bool is_abstract, bool is_unsigned, int bits, int runtime_type_kind) : Type(TYPE_INTEGER), - is_abstract_(is_abstract), is_unsigned_(is_unsigned), bits_(bits), - runtime_type_kind_(runtime_type_kind) + is_abstract_(is_abstract), is_unsigned_(is_unsigned), is_byte_(false), + is_rune_(false), bits_(bits), runtime_type_kind_(runtime_type_kind) { } // Map names of integer types to the types themselves. @@ -1422,6 +1442,10 @@ class Integer_type : public Type bool is_abstract_; // True if this is an unsigned type. 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. int bits_; // The runtime type code used in the type descriptor for this type. |