Commit a14e122a by Ian Lance Taylor

compiler: deref receiver types in mangled names

    
    This was the original intent, as reflected in the long comment at the
    start of names.cc, but I forgot to implement it.
    
    Also, remove a leading ".0" from the final name.  That could occur for
    a method whose receiver type starts with 'u', as in that case we
    prepend a space to the mangled name, to avoid confusion with the
    Unicode mangling, and the space turns into ".0".
    
    Also, if the Unicode encoding would cause the final to start with
    "..u" or "..U", add a leading underscore.
    
    Patch gotest to not get fooled by some names.
    
    The result of these changes is that all symbols start with a letter or
    an underscore.
    
    Reviewed-on: https://go-review.googlesource.com/90015

From-SVN: r257068
parent 9aba6f77
553e04735d1be372c596c720bcaea27e050b13a6 203cbe7d3820fa03c965a01f72461f71588fe952
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -104,6 +104,14 @@ go_encode_id(const std::string &id) ...@@ -104,6 +104,14 @@ go_encode_id(const std::string &id)
std::string ret; std::string ret;
const char* p = id.c_str(); const char* p = id.c_str();
const char* pend = p + id.length(); const char* pend = p + id.length();
// A leading ".0" is a space introduced before a mangled type name
// that starts with a 'u' or 'U', to avoid confusion with the
// mangling used here. We don't need a leading ".0", and we don't
// want symbols that start with '.', so remove it.
if (p[0] == '.' && p[1] == '0')
p += 2;
while (p < pend) while (p < pend)
{ {
unsigned int c; unsigned int c;
...@@ -115,16 +123,19 @@ go_encode_id(const std::string &id) ...@@ -115,16 +123,19 @@ go_encode_id(const std::string &id)
go_assert(!char_needs_encoding(c)); go_assert(!char_needs_encoding(c));
ret += c; ret += c;
} }
else if (c < 0x10000)
{
char buf[16];
snprintf(buf, sizeof buf, "..u%04x", c);
ret += buf;
}
else else
{ {
char buf[16]; char buf[16];
snprintf(buf, sizeof buf, "..U%08x", c); if (c < 0x10000)
snprintf(buf, sizeof buf, "..u%04x", c);
else
snprintf(buf, sizeof buf, "..U%08x", c);
// We don't want a symbol to start with '.', so add a prefix
// if needed.
if (ret.empty())
ret += '_';
ret += buf; ret += buf;
} }
p += len; p += len;
......
...@@ -213,7 +213,7 @@ Gogo::function_asm_name(const std::string& go_name, const Package* package, ...@@ -213,7 +213,7 @@ Gogo::function_asm_name(const std::string& go_name, const Package* package,
{ {
std::string ret; std::string ret;
if (rtype != NULL) if (rtype != NULL)
ret = rtype->mangled_name(this); ret = rtype->deref()->mangled_name(this);
else if (package == NULL) else if (package == NULL)
ret = this->pkgpath_symbol(); ret = this->pkgpath_symbol();
else else
...@@ -892,14 +892,7 @@ Named_type::append_mangled_type_name(Gogo* gogo, bool use_alias, ...@@ -892,14 +892,7 @@ Named_type::append_mangled_type_name(Gogo* gogo, bool use_alias,
const Typed_identifier* rcvr = const Typed_identifier* rcvr =
this->in_function_->func_value()->type()->receiver(); this->in_function_->func_value()->type()->receiver();
if (rcvr != NULL) if (rcvr != NULL)
{ ret->append(rcvr->type()->deref()->mangled_name(gogo));
std::string m = rcvr->type()->mangled_name(gogo);
// Turn a leading ".1" back into "*" since we are going
// to type-mangle this name again.
if (m.compare(0, 2, ".1") == 0)
m = "*" + m.substr(2);
ret->append(m);
}
else if (this->in_function_->package() == NULL) else if (this->in_function_->package() == NULL)
ret->append(gogo->pkgpath_symbol()); ret->append(gogo->pkgpath_symbol());
else else
...@@ -956,7 +949,7 @@ Gogo::type_descriptor_name(Type* type, Named_type* nt) ...@@ -956,7 +949,7 @@ Gogo::type_descriptor_name(Type* type, Named_type* nt)
const Typed_identifier* rcvr = const Typed_identifier* rcvr =
in_function->func_value()->type()->receiver(); in_function->func_value()->type()->receiver();
if (rcvr != NULL) if (rcvr != NULL)
ret.append(rcvr->type()->mangled_name(this)); ret.append(rcvr->type()->deref()->mangled_name(this));
else if (in_function->package() == NULL) else if (in_function->package() == NULL)
ret.append(this->pkgpath_symbol()); ret.append(this->pkgpath_symbol());
else else
......
...@@ -730,7 +730,7 @@ func TestMutexProfile(t *testing.T) { ...@@ -730,7 +730,7 @@ func TestMutexProfile(t *testing.T) {
stks := stacks(p) stks := stacks(p)
for _, want := range [][]string{ for _, want := range [][]string{
// {"sync.(*Mutex).Unlock", "pprof.blockMutex.func1"}, // {"sync.(*Mutex).Unlock", "pprof.blockMutex.func1"},
{".1sync.Mutex.Unlock", "pprof.blockMutex..func1"}, {"sync.Mutex.Unlock", "pprof.blockMutex..func1"},
} { } {
if !containsStack(stks, want) { if !containsStack(stks, want) {
t.Errorf("No matching stack entry for %+v", want) t.Errorf("No matching stack entry for %+v", want)
......
...@@ -518,7 +518,7 @@ localname() { ...@@ -518,7 +518,7 @@ localname() {
pattern='Test([^a-z].*)?' pattern='Test([^a-z].*)?'
# The -p option tells GNU nm not to sort. # The -p option tells GNU nm not to sort.
# The -v option tells Solaris nm to sort by value. # The -v option tells Solaris nm to sort by value.
tests=$($NM -p -v _gotest_.o $xofile | egrep " $text .*\."$pattern'$' | grep -v '\..*\..*\.' | fgrep -v '$' | fgrep -v ' __go_' | sed 's/.* //' | $symtogo) tests=$($NM -p -v _gotest_.o $xofile | egrep " $text .*\."$pattern'$' | grep -v '\..*\.' | fgrep -v '$' | fgrep -v ' __go_' | sed 's/.* //' | $symtogo)
if [ "x$tests" = x ]; then if [ "x$tests" = x ]; then
echo 'gotest: warning: no tests matching '$pattern in _gotest_.o $xofile 1>&2 echo 'gotest: warning: no tests matching '$pattern in _gotest_.o $xofile 1>&2
exit 2 exit 2
......
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