aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/gogo.h17
-rw-r--r--gcc/go/gofrontend/names.cc136
-rw-r--r--gcc/go/gofrontend/types.cc4
-rw-r--r--gcc/go/gofrontend/types.h44
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;