3818237cd5111fdd089f9c9470d384eebbe6ee1e diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 429904a2b8f..ec7e2ab1acf 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -8c056e335cecec67d1d223a329b7ba4dac778a65 +1cb83a415e86ab4de0d436d277377d8fc060cb61 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/ast-dump.cc b/gcc/go/gofrontend/ast-dump.cc index eca0bf1fad2..12f49e68700 100644 --- a/gcc/go/gofrontend/ast-dump.cc +++ b/gcc/go/gofrontend/ast-dump.cc @@ -223,14 +223,7 @@ Ast_dump_context::dump_type(const Type* t) if (t == NULL) this->ostream() << "(nil type)"; else - // FIXME: write a type pretty printer instead of - // using mangled names. - if (this->gogo_ != NULL) - { - Backend_name bname; - t->backend_name(this->gogo_, &bname); - this->ostream() << "(" << bname.name() << ")"; - } + this->ostream() << "(" << t->message_name() << ")"; } // Dump a textual representation of a block to the diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index b349ad10d6f..a39cfbf7679 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -270,6 +270,16 @@ Type::set_is_error() this->classification_ = TYPE_ERROR; } +// Return a string version of this type to use in an error message. + +std::string +Type::message_name() const +{ + std::string ret; + this->do_message_name(&ret); + return ret; +} + // If this is a pointer type, return the type to which it points. // Otherwise, return NULL. @@ -742,16 +752,14 @@ Type::are_assignable(const Type* lhs, const Type* rhs, std::string* reason) { if (rhs->interface_type() != NULL) reason->assign(_("need explicit conversion")); - else if (lhs_orig->named_type() != NULL - && rhs_orig->named_type() != NULL) + else { - size_t len = (lhs_orig->named_type()->name().length() - + rhs_orig->named_type()->name().length() - + 100); + const std::string& lhs_name(lhs_orig->message_name()); + const std::string& rhs_name(rhs_orig->message_name()); + size_t len = lhs_name.length() + rhs_name.length() + 100; char* buf = new char[len]; snprintf(buf, len, _("cannot use type %s as type %s"), - rhs_orig->named_type()->message_name().c_str(), - lhs_orig->named_type()->message_name().c_str()); + rhs_name.c_str(), lhs_name.c_str()); reason->assign(buf); delete[] buf; } @@ -4244,6 +4252,33 @@ Integer_type::is_identical(const Integer_type* t) const return this->is_abstract_ == t->is_abstract_; } +// Message name. + +void +Integer_type::do_message_name(std::string* ret) const +{ + ret->append("is_byte_) + ret->append("byte"); + else if (this->is_rune_) + ret->append("rune"); + else + { + if (this->is_unsigned_) + ret->push_back('u'); + if (this->is_abstract_) + ret->append("int"); + else + { + ret->append("int"); + char buf[10]; + snprintf(buf, sizeof buf, "%d", this->bits_); + ret->append(buf); + } + } + ret->push_back('>'); +} + // Hash code. unsigned int @@ -4382,6 +4417,21 @@ Float_type::is_identical(const Float_type* t) const return this->is_abstract_ == t->is_abstract_; } +// Message name. + +void +Float_type::do_message_name(std::string* ret) const +{ + ret->append("is_abstract_) + { + char buf[10]; + snprintf(buf, sizeof buf, "%d", this->bits_); + ret->append(buf); + } + ret->push_back('>'); +} + // Hash code. unsigned int @@ -4496,6 +4546,21 @@ Complex_type::is_identical(const Complex_type *t) const return this->is_abstract_ == t->is_abstract_; } +// Message name. + +void +Complex_type::do_message_name(std::string* ret) const +{ + ret->append("is_abstract_) + { + char buf[10]; + snprintf(buf, sizeof buf, "%d", this->bits_); + ret->append(buf); + } + ret->push_back('>'); +} + // Hash code. unsigned int @@ -4661,6 +4726,10 @@ class Sink_type : public Type { } protected: + void + do_message_name(std::string* ret) const + { ret->append(""); } + bool do_compare_is_identity(Gogo*) { return false; } @@ -4696,6 +4765,70 @@ Type::make_sink_type() // Class Function_type. +// Message name. + +void +Function_type::do_message_name(std::string* ret) const +{ + ret->append("func"); + if (this->receiver_ != NULL) + { + ret->append(" (receiver "); + this->append_message_name(this->receiver_->type(), ret); + ret->append(") "); + } + this->append_signature(ret); +} + +// Append just the signature to RET. + +void +Function_type::append_signature(std::string* ret) const +{ + ret->push_back('('); + if (this->parameters_ != NULL) + { + bool first = true; + for (Typed_identifier_list::const_iterator p = this->parameters_->begin(); + p != this->parameters_->end(); + ++p) + { + if (first) + first = false; + else + ret->append(", "); + this->append_message_name(p->type(), ret); + } + } + ret->push_back(')'); + + if (this->results_ != NULL) + { + if (this->results_->size() == 1) + { + ret->push_back(' '); + this->append_message_name(this->results_->front().type(), ret); + } + else + { + ret->append(" ("); + bool first = true; + for (Typed_identifier_list::const_iterator p = + this->results_->begin(); + p != this->results_->end(); + ++p) + { + if (first) + first = false; + else + ret->append(", "); + this->append_message_name(p->type(), ret); + } + ret->push_back(')'); + } + } +} + // Traversal. int @@ -5548,6 +5681,20 @@ Type::make_backend_function_type(Typed_identifier* receiver, // Class Pointer_type. +// Message name. + +void +Pointer_type::do_message_name(std::string* ret) const +{ + if (this->to_type_->is_void_type()) + ret->append("unsafe.Pointer"); + else + { + ret->push_back('*'); + this->append_message_name(this->to_type_, ret); + } +} + // Traversal. int @@ -5764,6 +5911,10 @@ class Call_multiple_result_type : public Type { } protected: + void + do_message_name(std::string* ret) const + { ret->append(""); } + bool do_has_pointer() const { return false; } @@ -5940,6 +6091,41 @@ Struct_type::Identical_structs Struct_type::identical_structs; Struct_type::Struct_method_tables Struct_type::struct_method_tables; +// Message name. + +void +Struct_type::do_message_name(std::string* ret) const +{ + if (this->fields_ == NULL || this->fields_->empty()) + { + ret->append("struct{}"); + return; + } + + ret->append("struct {"); + + bool first = true; + for (Struct_field_list::const_iterator p = this->fields_->begin(); + p != this->fields_->end(); + ++p) + { + if (first) + first = false; + else + ret->append("; "); + + if (!p->is_anonymous()) + { + ret->append(p->field_name()); + ret->push_back(' '); + } + + this->append_message_name(p->type(), ret); + } + + ret->append(" }"); +} + // Traversal. int @@ -7344,6 +7530,35 @@ Array_type::is_identical(const Array_type* t, int flags) const return false; } +// Message name. + +void +Array_type::do_message_name(std::string* ret) const +{ + ret->push_back('['); + if (!this->is_slice_type()) + { + Numeric_constant nc; + if (!this->length_->numeric_constant_value(&nc)) + ret->append(""); + else + { + mpz_t val; + if (!nc.to_int(&val)) + ret->append(""); + else + { + char* s = mpz_get_str(NULL, 10, val); + ret->append(s); + free(s); + mpz_clear(val); + } + } + } + ret->push_back(']'); + this->append_message_name(this->element_type_, ret); +} + // Traversal. int @@ -8249,6 +8464,17 @@ Map_type::backend_zero_value(Gogo* gogo) return zvar; } +// Message name. + +void +Map_type::do_message_name(std::string* ret) const +{ + ret->append("map["); + this->append_message_name(this->key_type_, ret); + ret->push_back(']'); + this->append_message_name(this->val_type_, ret); +} + // Traversal. int @@ -8803,6 +9029,20 @@ Type::make_map_type(Type* key_type, Type* val_type, Location location) // Class Channel_type. +// Message name. + +void +Channel_type::do_message_name(std::string* ret) const +{ + if (!this->may_send_) + ret->append("<-"); + ret->append("chan"); + if (!this->may_receive_) + ret->append("<-"); + ret->push_back(' '); + this->append_message_name(this->element_type_, ret); +} + // Verify. bool @@ -9053,6 +9293,45 @@ Interface_type::method_count() const return this->all_methods_ == NULL ? 0 : this->all_methods_->size(); } +// Message name. + +void +Interface_type::do_message_name(std::string* ret) const +{ + const Typed_identifier_list* methods = (this->methods_are_finalized_ + ? this->all_methods_ + : this->parse_methods_); + if (methods == NULL || methods->empty()) + { + ret->append("interface{}"); + return; + } + + ret->append("interface {"); + + bool first = true; + for (Typed_identifier_list::const_iterator p = methods->begin(); + p != methods->end(); + ++p) + { + if (first) + first = false; + else + ret->append("; "); + + if (!p->name().empty()) + ret->append(p->name()); + + Function_type* ft = p->type()->function_type(); + if (ft == NULL) + this->append_message_name(p->type(), ret); + else + ft->append_signature(ret); + } + + ret->append(" }"); +} + // Traversal. int @@ -10295,10 +10574,10 @@ Named_type::name() const // Return the name of the type to use in an error message. -std::string -Named_type::message_name() const +void +Named_type::do_message_name(std::string* ret) const { - return this->named_object_->message_name(); + ret->append(this->named_object_->message_name()); } // Return the base type for this type. We have to be careful about @@ -12819,6 +13098,17 @@ Forward_declaration_type::add_existing_method(Named_object* nom) no->type_declaration_value()->add_existing_method(nom); } +// Message name. + +void +Forward_declaration_type::do_message_name(std::string* ret) const +{ + if (this->is_defined()) + this->append_message_name(this->real_type(), ret); + else + ret->append(this->named_object_->message_name()); +} + // Traversal. int diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index 3dd32799d74..cbc7ce0aa0e 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -575,6 +575,10 @@ class Type static Named_type* make_builtin_named_type(const char* name, Type* type); + // Return a string version of this type to use in an error message. + std::string + message_name() const; + // Traverse a type. static int traverse(Type*, Traverse*); @@ -1095,6 +1099,10 @@ class Type // Functions implemented by the child class. + // Message name. + virtual void + do_message_name(std::string*) const = 0; + // Traverse the subtypes. virtual int do_traverse(Traverse*); @@ -1195,6 +1203,11 @@ class Type type_descriptor_constructor(Gogo*, int runtime_type_kind, Named_type*, const Methods*, bool only_value_methods); + // For the benefit of child class message name construction. + void + append_message_name(const Type* type, std::string* ret) const + { type->do_message_name(ret); } + // For the benefit of child class reflection string generation. void append_reflection(const Type* type, Gogo* gogo, std::string* ret) const @@ -1656,6 +1669,10 @@ class Error_type : public Type { } protected: + void + do_message_name(std::string* ret) const + { ret->append(""); } + bool do_compare_is_identity(Gogo*) { return false; } @@ -1683,6 +1700,10 @@ class Void_type : public Type { } protected: + void + do_message_name(std::string* ret) const + { ret->append("void"); } + bool do_compare_is_identity(Gogo*) { return false; } @@ -1712,6 +1733,10 @@ class Boolean_type : public Type { } protected: + void + do_message_name(std::string* ret) const + { ret->append(""); } + bool do_compare_is_identity(Gogo*) { return true; } @@ -1797,6 +1822,9 @@ class Integer_type : public Type { this->is_rune_ = true; } protected: + void + do_message_name(std::string* ret) const; + bool do_compare_is_identity(Gogo*) { return true; } @@ -1874,6 +1902,9 @@ class Float_type : public Type is_identical(const Float_type* t) const; protected: + void + do_message_name(std::string* ret) const; + bool do_compare_is_identity(Gogo*) { return false; } @@ -1952,6 +1983,9 @@ class Complex_type : public Type is_identical(const Complex_type* t) const; protected: + void + do_message_name(std::string*) const; + bool do_compare_is_identity(Gogo*) { return false; } @@ -2009,6 +2043,10 @@ class String_type : public Type { } protected: + void + do_message_name(std::string* ret) const + { ret->append(""); } + bool do_has_pointer() const { return true; } @@ -2166,7 +2204,14 @@ class Function_type : public Type is_backend_function_type() const { return false; } + // Append just the signature of the function type. + void + append_signature(std::string*) const; + protected: + void + do_message_name(std::string*) const; + int do_traverse(Traverse*); @@ -2293,6 +2338,9 @@ class Pointer_type : public Type make_pointer_type_descriptor_type(); protected: + void + do_message_name(std::string*) const; + int do_traverse(Traverse*); @@ -2346,6 +2394,10 @@ class Nil_type : public Type { } protected: + void + do_message_name(std::string* ret) const + { ret->append(""); } + bool do_compare_is_identity(Gogo*) { return false; } @@ -2671,6 +2723,9 @@ class Struct_type : public Type write_to_c_header(std::ostream&) const; protected: + void + do_message_name(std::string*) const; + int do_traverse(Traverse*); @@ -2851,6 +2906,9 @@ class Array_type : public Type write_equal_function(Gogo*, Named_object* function, Named_type*); protected: + void + do_message_name(std::string*) const; + int do_traverse(Traverse* traverse); @@ -2999,6 +3057,9 @@ class Map_type : public Type static const int bucket_size = 8; protected: + void + do_message_name(std::string*) const; + int do_traverse(Traverse*); @@ -3118,6 +3179,9 @@ class Channel_type : public Type select_case_type(); protected: + void + do_message_name(std::string*) const; + int do_traverse(Traverse* traverse) { return Type::traverse(this->element_type_, traverse); } @@ -3273,6 +3337,9 @@ class Interface_type : public Type { return this->methods_are_finalized_; } protected: + void + do_message_name(std::string*) const; + int do_traverse(Traverse*); @@ -3450,12 +3517,6 @@ class Named_type : public Type const std::string& name() const; - // Return the name of the type for an error message. The difference - // is that if the type is defined in a different package, this will - // return PACKAGE.NAME. - std::string - message_name() const; - // Return the underlying type. Type* real_type() @@ -3599,6 +3660,9 @@ class Named_type : public Type convert(Gogo*); protected: + void + do_message_name(std::string* ret) const; + int do_traverse(Traverse* traverse) { return Type::traverse(this->type_, traverse); } @@ -3758,6 +3822,9 @@ class Forward_declaration_type : public Type add_existing_method(Named_object*); protected: + void + do_message_name(std::string*) const; + int do_traverse(Traverse* traverse);