summaryrefslogtreecommitdiff
path: root/libgo/go/debug/gosym/symtab.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/debug/gosym/symtab.go')
-rw-r--r--libgo/go/debug/gosym/symtab.go55
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 {