blob: fec7a03912e18eb16977d3e4d45f6f81e555360c [file] [log] [blame]
// 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()
}