// 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() }