diff options
Diffstat (limited to 'libgo/go/debug/gosym/symtab.go')
-rw-r--r-- | libgo/go/debug/gosym/symtab.go | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/libgo/go/debug/gosym/symtab.go b/libgo/go/debug/gosym/symtab.go index 00701c2875a..4e63f1cdf70 100644 --- a/libgo/go/debug/gosym/symtab.go +++ b/libgo/go/debug/gosym/symtab.go @@ -32,10 +32,28 @@ type Sym struct { // Static reports whether this symbol is static (not visible outside its file). func (s *Sym) Static() bool { return s.Type >= 'a' } +// nameWithoutInst returns s.Name if s.Name has no brackets (does not reference an +// instantiated type, function, or method). If s.Name contains brackets, then it +// returns s.Name with all the contents between (and including) the outermost left +// and right bracket removed. This is useful to ignore any extra slashes or dots +// inside the brackets from the string searches below, where needed. +func (s *Sym) nameWithoutInst() string { + start := strings.Index(s.Name, "[") + if start < 0 { + return s.Name + } + end := strings.LastIndex(s.Name, "]") + if end < 0 { + // Malformed name, should contain closing bracket too. + return s.Name + } + return s.Name[0:start] + s.Name[end+1:] +} + // PackageName returns the package part of the symbol name, // or the empty string if there is none. func (s *Sym) PackageName() string { - name := s.Name + name := s.nameWithoutInst() // A prefix of "type." and "go." is a compiler-generated symbol that doesn't belong to any package. // See variable reservedimports in cmd/compile/internal/gc/subr.go @@ -55,23 +73,46 @@ func (s *Sym) PackageName() string { } // ReceiverName returns the receiver type name of this symbol, -// or the empty string if there is none. +// or the empty string if there is none. A receiver name is only detected in +// the case that s.Name is fully-specified with a package name. func (s *Sym) ReceiverName() string { - pathend := strings.LastIndex(s.Name, "/") + name := s.nameWithoutInst() + // If we find a slash in name, it should precede any bracketed expression + // that was removed, so pathend will apply correctly to name and s.Name. + pathend := strings.LastIndex(name, "/") if pathend < 0 { pathend = 0 } - l := strings.Index(s.Name[pathend:], ".") - r := strings.LastIndex(s.Name[pathend:], ".") + // Find the first dot after pathend (or from the beginning, if there was + // no slash in name). + l := strings.Index(name[pathend:], ".") + // Find the last dot after pathend (or the beginnng). + r := strings.LastIndex(name[pathend:], ".") if l == -1 || r == -1 || l == r { + // There is no receiver if we didn't find two distinct dots after pathend. return "" } + // Given there is a trailing '.' that is in name, find it now in s.Name. + // pathend+l should apply to s.Name, because it should be the dot in the + // package name. + r = strings.LastIndex(s.Name[pathend:], ".") return s.Name[pathend+l+1 : pathend+r] } // BaseName returns the symbol name without the package or receiver name. func (s *Sym) BaseName() string { - if i := strings.LastIndex(s.Name, "."); i != -1 { + name := s.nameWithoutInst() + if i := strings.LastIndex(name, "."); i != -1 { + if s.Name != name { + brack := strings.Index(s.Name, "[") + if i > brack { + // BaseName is a method name after the brackets, so + // recalculate for s.Name. Otherwise, i applies + // correctly to s.Name, since it is before the + // brackets. + i = strings.LastIndex(s.Name, ".") + } + } return s.Name[i+1:] } return s.Name @@ -710,7 +751,7 @@ func (e *UnknownLineError) Error() string { type DecodingError struct { off int msg string - val interface{} + val any } func (e *DecodingError) Error() string { |