diff options
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.h | 17 | ||||
-rw-r--r-- | gcc/go/gofrontend/names.cc | 136 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 4 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.h | 44 |
5 files changed, 144 insertions, 59 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index dc2682d..681debb 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -0d0b423739b2fee9788cb6cb8af9ced29375e545 +3e8f49a2137a87fdaba51c3002ddbe41ab18ed46 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/gogo.h b/gcc/go/gofrontend/gogo.h index f22d476..49d7bd9 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -67,7 +67,7 @@ class Backend_name public: Backend_name() : prefix_(NULL), components_(), count_(0), suffix_(), - is_asm_name_(false) + is_asm_name_(false), is_non_identifier_(false) {} // Set the prefix. Prefixes are always constant strings. @@ -120,6 +120,18 @@ class Backend_name this->is_asm_name_ = true; } + // Whether some component includes some characters that can't appear + // in an identifier. + bool + is_non_identifier() const + { return this->is_non_identifier_; } + + // Record that some component includes some character that can't + // appear in an identifier. + void + set_is_non_identifier() + { this->is_non_identifier_ = true; } + // Get the user visible name. std::string name() const; @@ -150,6 +162,9 @@ class Backend_name std::string suffix_; // True if components_[0] is an assembler name specified by the user. bool is_asm_name_; + // True if some component includes some character that can't + // normally appear in an identifier. + bool is_non_identifier_; }; // An initialization function for an imported package. This is a diff --git a/gcc/go/gofrontend/names.cc b/gcc/go/gofrontend/names.cc index 8e73e5e..f85d84c 100644 --- a/gcc/go/gofrontend/names.cc +++ b/gcc/go/gofrontend/names.cc @@ -186,6 +186,20 @@ // struct tag, the brace or backslash will be backslash quoted, before // underscore encoding. // +// Many of these names will be visible in the debugger. The debugger +// will be given these names before applying any underscore encoding. +// These user names do not have to be unique--they are only used by +// the debugger, not the linker--so this is OK. However, there is an +// exception: if the name would otherwise include characters that +// can't normally appear in an identifier, then the user name will +// also be underscore encoded. This avoids problems with +// communicating the debug info to the assembler and with handling the +// debug info in the debugger. A Go-aware debugger will need to know +// whether to apply underscore decoding to a name before showing it to +// the user. We indicate this by adding a prefix of "g.", and +// assuming that cases of a package path of "g" are unusual. This +// prefix will only appear in the user name, not the assembler name. +// // The underscore encoding is, naturally, an underscore followed by // other characters. As there are various characters that commonly // appear in type literals and in package paths, we have a set of @@ -512,7 +526,7 @@ Gogo::recover_thunk_name(const std::string& name, const Type* rtype) if (rtype != NULL) { Backend_name bname; - rtype->backend_name(this, &bname); + rtype->deref()->backend_name(this, &bname); ret = bname.name(); ret.append(1, '.'); } @@ -634,37 +648,45 @@ Type::backend_name(Gogo* gogo, Backend_name* bname) const } std::string name; + bool is_non_identifier = false; // The do_symbol_name virtual function will set RET to the mangled // name before encoding. - this->do_mangled_name(gogo, &name); + this->do_mangled_name(gogo, &name, &is_non_identifier); bname->add(name); + if (is_non_identifier) + bname->set_is_non_identifier(); } // The mangled name is implemented as a method on each instance of // Type. void -Error_type::do_mangled_name(Gogo*, std::string* ret) const +Error_type::do_mangled_name(Gogo*, std::string* ret, + bool* is_non_identifier) const { ret->append("{error}"); + *is_non_identifier = true; } void -Void_type::do_mangled_name(Gogo*, std::string* ret) const +Void_type::do_mangled_name(Gogo*, std::string* ret, + bool* is_non_identifier) const { ret->append("{void}"); + *is_non_identifier = true; } void -Boolean_type::do_mangled_name(Gogo*, std::string* ret) const +Boolean_type::do_mangled_name(Gogo*, std::string* ret, bool*) const { ret->append("bool"); } void -Integer_type::do_mangled_name(Gogo*, std::string* ret) const +Integer_type::do_mangled_name(Gogo*, std::string* ret, + bool* is_non_identifier) const { char buf[100]; snprintf(buf, sizeof buf, "%s%si%d", @@ -672,43 +694,53 @@ Integer_type::do_mangled_name(Gogo*, std::string* ret) const this->is_unsigned_ ? "u" : "", this->bits_); ret->append(buf); + if (this->is_abstract_) + *is_non_identifier = true; } void -Float_type::do_mangled_name(Gogo*, std::string* ret) const +Float_type::do_mangled_name(Gogo*, std::string* ret, + bool* is_non_identifier) const { char buf[100]; snprintf(buf, sizeof buf, "%sfloat%d", this->is_abstract_ ? "{abstract}" : "", this->bits_); ret->append(buf); + if (this->is_abstract_) + *is_non_identifier = true; } void -Complex_type::do_mangled_name(Gogo*, std::string* ret) const +Complex_type::do_mangled_name(Gogo*, std::string* ret, + bool* is_non_identifier) const { char buf[100]; snprintf(buf, sizeof buf, "%sc%d", this->is_abstract_ ? "{abstract}" : "", this->bits_); ret->append(buf); + if (this->is_abstract_) + *is_non_identifier = true; } void -String_type::do_mangled_name(Gogo*, std::string* ret) const +String_type::do_mangled_name(Gogo*, std::string* ret, bool*) const { ret->append("string"); } void -Function_type::do_mangled_name(Gogo* gogo, std::string* ret) const +Function_type::do_mangled_name(Gogo* gogo, std::string* ret, + bool* is_non_identifier) const { ret->append("func"); if (this->receiver_ != NULL) { ret->push_back('('); - this->append_mangled_name(this->receiver_->type(), gogo, ret); + this->append_mangled_name(this->receiver_->type(), gogo, ret, + is_non_identifier); ret->append(")"); } @@ -727,7 +759,8 @@ Function_type::do_mangled_name(Gogo* gogo, std::string* ret) const ret->push_back(','); if (this->is_varargs_ && p + 1 == params->end()) ret->append("..."); - this->append_mangled_name(p->type(), gogo, ret); + this->append_mangled_name(p->type(), gogo, ret, + is_non_identifier); } } ret->push_back(')'); @@ -745,27 +778,34 @@ Function_type::do_mangled_name(Gogo* gogo, std::string* ret) const first = false; else ret->append(","); - this->append_mangled_name(p->type(), gogo, ret); + this->append_mangled_name(p->type(), gogo, ret, is_non_identifier); } } ret->push_back(')'); + + *is_non_identifier = true; } void -Pointer_type::do_mangled_name(Gogo* gogo, std::string* ret) const +Pointer_type::do_mangled_name(Gogo* gogo, std::string* ret, + bool* is_non_identifier) const { ret->push_back('*'); - this->append_mangled_name(this->to_type_, gogo, ret); + this->append_mangled_name(this->to_type_, gogo, ret, is_non_identifier); + *is_non_identifier = true; } void -Nil_type::do_mangled_name(Gogo*, std::string* ret) const +Nil_type::do_mangled_name(Gogo*, std::string* ret, + bool* is_non_identifier) const { ret->append("{nil}"); + *is_non_identifier = true; } void -Struct_type::do_mangled_name(Gogo* gogo, std::string* ret) const +Struct_type::do_mangled_name(Gogo* gogo, std::string* ret, + bool* is_non_identifier) const { ret->append("struct{"); @@ -796,9 +836,10 @@ Struct_type::do_mangled_name(Gogo* gogo, std::string* ret) const if (p->is_anonymous() && p->type()->named_type() != NULL && p->type()->named_type()->is_alias()) - p->type()->named_type()->append_symbol_type_name(gogo, true, ret); + p->type()->named_type()->append_symbol_type_name(gogo, true, ret, + is_non_identifier); else - this->append_mangled_name(p->type(), gogo, ret); + this->append_mangled_name(p->type(), gogo, ret, is_non_identifier); if (p->has_tag()) { @@ -813,10 +854,13 @@ Struct_type::do_mangled_name(Gogo* gogo, std::string* ret) const } ret->push_back('}'); + + *is_non_identifier = true; } void -Array_type::do_mangled_name(Gogo* gogo, std::string* ret) const +Array_type::do_mangled_name(Gogo* gogo, std::string* ret, + bool* is_non_identifier) const { ret->push_back('['); if (this->length_ != NULL) @@ -841,20 +885,24 @@ Array_type::do_mangled_name(Gogo* gogo, std::string* ret) const ret->append("x"); } ret->push_back(']'); - this->append_mangled_name(this->element_type_, gogo, ret); + this->append_mangled_name(this->element_type_, gogo, ret, is_non_identifier); + *is_non_identifier = true; } void -Map_type::do_mangled_name(Gogo* gogo, std::string* ret) const +Map_type::do_mangled_name(Gogo* gogo, std::string* ret, + bool* is_non_identifier) const { ret->append("map["); - this->append_mangled_name(this->key_type_, gogo, ret); + this->append_mangled_name(this->key_type_, gogo, ret, is_non_identifier); ret->push_back(']'); - this->append_mangled_name(this->val_type_, gogo, ret); + this->append_mangled_name(this->val_type_, gogo, ret, is_non_identifier); + *is_non_identifier = true; } void -Channel_type::do_mangled_name(Gogo* gogo, std::string* ret) const +Channel_type::do_mangled_name(Gogo* gogo, std::string* ret, + bool* is_non_identifier) const { if (!this->may_send_) ret->append("<-"); @@ -862,11 +910,13 @@ Channel_type::do_mangled_name(Gogo* gogo, std::string* ret) const if (!this->may_receive_) ret->append("<-"); ret->push_back(' '); - this->append_mangled_name(this->element_type_, gogo, ret); + this->append_mangled_name(this->element_type_, gogo, ret, is_non_identifier); + *is_non_identifier = true; } void -Interface_type::do_mangled_name(Gogo* gogo, std::string* ret) const +Interface_type::do_mangled_name(Gogo* gogo, std::string* ret, + bool* is_non_identifier) const { go_assert(this->methods_are_finalized_); @@ -892,25 +942,29 @@ Interface_type::do_mangled_name(Gogo* gogo, std::string* ret) const ret->push_back(' '); } - this->append_mangled_name(p->type(), gogo, ret); + this->append_mangled_name(p->type(), gogo, ret, is_non_identifier); } this->seen_ = false; } ret->push_back('}'); + + *is_non_identifier = true; } void -Named_type::do_mangled_name(Gogo* gogo, std::string* ret) const +Named_type::do_mangled_name(Gogo* gogo, std::string* ret, + bool* is_non_identifier) const { - this->append_symbol_type_name(gogo, false, ret); + this->append_symbol_type_name(gogo, false, ret, is_non_identifier); } void -Forward_declaration_type::do_mangled_name(Gogo* gogo, std::string* ret) const +Forward_declaration_type::do_mangled_name(Gogo* gogo, std::string* ret, + bool *is_non_identifier) const { if (this->is_defined()) - this->append_mangled_name(this->real_type(), gogo, ret); + this->append_mangled_name(this->real_type(), gogo, ret, is_non_identifier); else { const Named_object* no = this->named_object(); @@ -929,7 +983,8 @@ Forward_declaration_type::do_mangled_name(Gogo* gogo, std::string* ret) const void Named_type::append_symbol_type_name(Gogo* gogo, bool use_alias, - std::string* ret) const + std::string* ret, + bool* is_non_identifier) const { if (this->is_error_) return; @@ -938,7 +993,7 @@ Named_type::append_symbol_type_name(Gogo* gogo, bool use_alias, if (this->seen_alias_) return; this->seen_alias_ = true; - this->append_mangled_name(this->type_, gogo, ret); + this->append_mangled_name(this->type_, gogo, ret, is_non_identifier); this->seen_alias_ = false; return; } @@ -957,6 +1012,8 @@ Named_type::append_symbol_type_name(Gogo* gogo, bool use_alias, Backend_name bname; rcvr->type()->deref()->backend_name(gogo, &bname); ret->append(bname.name()); + if (bname.is_non_identifier()) + *is_non_identifier = true; } else if (this->in_function_->package() == NULL) ret->append(gogo->pkgpath()); @@ -1160,6 +1217,15 @@ Backend_name::name() const { if (this->is_asm_name_) return this->components_[0]; + + // If there is some character in the name that can't appear in an + // identifier, use the assembler name as the user name. This avoids + // possible problems in the assembler or debugger. The usual + // demangling scheme will still work. We use a prefix of "g." to + // tell the debugger about this. + if (this->is_non_identifier_) + return "g." + this->asm_name(); + std::string ret; if (this->prefix_ != NULL) ret.append(this->prefix_); @@ -1203,6 +1269,8 @@ Backend_name::optional_asm_name() const { if (this->is_asm_name_) return ""; + if (this->is_non_identifier_) + return this->asm_name(); for (int i = 0; i < this->count_; i++) if (go_id_needs_encoding(this->components_[i])) return this->asm_name(); diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index d2741f6..f9097d5 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -4602,7 +4602,7 @@ class Sink_type : public Type { go_unreachable(); } void - do_mangled_name(Gogo*, std::string*) const + do_mangled_name(Gogo*, std::string*, bool*) const { go_unreachable(); } }; @@ -5712,7 +5712,7 @@ class Call_multiple_result_type : public Type { go_assert(saw_errors()); } void - do_mangled_name(Gogo*, std::string*) const + do_mangled_name(Gogo*, std::string*, bool*) const { go_assert(saw_errors()); } private: diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index b7dd391..f2880f9 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -1140,7 +1140,7 @@ class Type do_reflection(Gogo*, std::string*) const = 0; virtual void - do_mangled_name(Gogo*, std::string*) const = 0; + do_mangled_name(Gogo*, std::string*, bool*) const = 0; virtual void do_export(Export*) const; @@ -1202,8 +1202,9 @@ class Type // For the benefit of child class mangling. void - append_mangled_name(const Type* type, Gogo* gogo, std::string* ret) const - { type->do_mangled_name(gogo, ret); } + append_mangled_name(const Type* type, Gogo* gogo, std::string* ret, + bool *is_non_identifier) const + { type->do_mangled_name(gogo, ret, is_non_identifier); } // Return the backend representation for the underlying type of a // named type. @@ -1664,7 +1665,7 @@ class Error_type : public Type do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string* ret) const; + do_mangled_name(Gogo*, std::string*, bool*) const; }; // The void type. @@ -1693,7 +1694,7 @@ class Void_type : public Type { } void - do_mangled_name(Gogo*, std::string* ret) const; + do_mangled_name(Gogo*, std::string*, bool*) const; }; // The boolean type. @@ -1722,7 +1723,7 @@ class Boolean_type : public Type { ret->append("bool"); } void - do_mangled_name(Gogo*, std::string* ret) const; + do_mangled_name(Gogo*, std::string*, bool*) const; }; // The type of an integer. @@ -1808,7 +1809,7 @@ protected: do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string*) const; + do_mangled_name(Gogo*, std::string*, bool*) const; private: Integer_type(bool is_abstract, bool is_unsigned, int bits, @@ -1894,7 +1895,7 @@ class Float_type : public Type do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string*) const; + do_mangled_name(Gogo*, std::string*, bool*) const; private: Float_type(bool is_abstract, int bits, int runtime_type_kind) @@ -1972,7 +1973,7 @@ class Complex_type : public Type do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string*) const; + do_mangled_name(Gogo*, std::string*, bool*) const; private: Complex_type(bool is_abstract, int bits, int runtime_type_kind) @@ -2026,7 +2027,7 @@ class String_type : public Type do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string* ret) const; + do_mangled_name(Gogo*, std::string*, bool*) const; private: // The named string type. @@ -2186,7 +2187,7 @@ class Function_type : public Type do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string*) const; + do_mangled_name(Gogo*, std::string*, bool*) const; void do_export(Export*) const; @@ -2315,7 +2316,7 @@ class Pointer_type : public Type do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string*) const; + do_mangled_name(Gogo*, std::string*, bool*) const; void do_export(Export*) const; @@ -2353,7 +2354,7 @@ class Nil_type : public Type { go_unreachable(); } void - do_mangled_name(Gogo*, std::string* ret) const; + do_mangled_name(Gogo*, std::string*, bool*) const; }; // The type of a field in a struct. @@ -2687,7 +2688,7 @@ class Struct_type : public Type do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string*) const; + do_mangled_name(Gogo*, std::string*, bool*) const; void do_export(Export*) const; @@ -2870,7 +2871,7 @@ class Array_type : public Type do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string*) const; + do_mangled_name(Gogo*, std::string*, bool*) const; void do_export(Export*) const; @@ -3008,7 +3009,7 @@ class Map_type : public Type do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string*) const; + do_mangled_name(Gogo*, std::string*, bool*) const; void do_export(Export*) const; @@ -3122,7 +3123,7 @@ class Channel_type : public Type do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string*) const; + do_mangled_name(Gogo*, std::string*, bool*) const; void do_export(Export*) const; @@ -3298,7 +3299,7 @@ class Interface_type : public Type do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string*) const; + do_mangled_name(Gogo*, std::string*, bool*) const; void do_export(Export*) const; @@ -3572,7 +3573,8 @@ class Named_type : public Type // Append the symbol type name as for Type::append_mangled_name, // but if USE_ALIAS use the alias name rather than the alias target. void - append_symbol_type_name(Gogo*, bool use_alias, std::string*) const; + append_symbol_type_name(Gogo*, bool use_alias, std::string*, + bool* is_non_identifier) const; // Import a named type. static void @@ -3619,7 +3621,7 @@ class Named_type : public Type do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string* ret) const; + do_mangled_name(Gogo*, std::string*, bool*) const; void do_export(Export*) const; @@ -3783,7 +3785,7 @@ class Forward_declaration_type : public Type do_reflection(Gogo*, std::string*) const; void - do_mangled_name(Gogo*, std::string* ret) const; + do_mangled_name(Gogo*, std::string*, bool*) const; void do_export(Export*) const; |