mirror of
https://github.com/golang/go
synced 2024-11-18 21:05:02 -07:00
713699d8ad
R=r CC=golang-dev https://golang.org/cl/13305043
72 lines
1.7 KiB
Go
72 lines
1.7 KiB
Go
// Copyright 2013 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package pointer
|
|
|
|
import (
|
|
"fmt"
|
|
"go/token"
|
|
"strings"
|
|
|
|
"code.google.com/p/go.tools/ssa"
|
|
)
|
|
|
|
// A Label is an abstract location or an instruction that allocates memory.
|
|
// A points-to set is (conceptually) a set of labels.
|
|
//
|
|
// (This is basically a pair of a Value that allocates an object and a
|
|
// subelement indicator within that object.)
|
|
//
|
|
// TODO(adonovan): local labels should include their context (CallGraphNode).
|
|
//
|
|
type Label struct {
|
|
Value ssa.Value
|
|
subelement *fieldInfo // e.g. ".a.b[*].c"
|
|
}
|
|
|
|
func (l *Label) Pos() token.Pos {
|
|
if l.Value != nil {
|
|
return l.Value.Pos()
|
|
}
|
|
return token.NoPos
|
|
}
|
|
|
|
func (l *Label) String() string {
|
|
var s string
|
|
switch v := l.Value.(type) {
|
|
case *ssa.Function, *ssa.Global:
|
|
s = v.String()
|
|
|
|
case *ssa.Const:
|
|
s = v.Name()
|
|
|
|
case *ssa.Alloc:
|
|
s = v.Comment
|
|
if s == "" {
|
|
s = "alloc"
|
|
}
|
|
|
|
case *ssa.Call:
|
|
// Currently only calls to append can allocate objects.
|
|
if v.Call.Value.(*ssa.Builtin).Object().Name() != "append" {
|
|
panic("unhandled *ssa.Call label: " + v.Name())
|
|
}
|
|
s = "append"
|
|
|
|
case *ssa.MakeMap, *ssa.MakeChan, *ssa.MakeSlice, *ssa.Convert:
|
|
s = strings.ToLower(strings.TrimPrefix(fmt.Sprintf("%T", v), "*ssa."))
|
|
|
|
case *ssa.MakeInterface:
|
|
// MakeInterface is usually implicit in Go source (so
|
|
// Pos()==0), and interfaces objects may be allocated
|
|
// synthetically (so no *MakeInterface data).
|
|
s = "makeinterface:" + v.X.Type().String()
|
|
|
|
default:
|
|
panic(fmt.Sprintf("unhandled Label.Value type: %T", v))
|
|
}
|
|
|
|
return s + l.subelement.path()
|
|
}
|