diff --git a/oracle/peers.go b/oracle/peers.go index 65e7ac2d3d5..822c8db58d7 100644 --- a/oracle/peers.go +++ b/oracle/peers.go @@ -14,6 +14,7 @@ import ( "code.google.com/p/go.tools/oracle/serial" "code.google.com/p/go.tools/pointer" "code.google.com/p/go.tools/ssa" + "code.google.com/p/go.tools/ssa/ssautil" ) // peers enumerates, for a given channel send (or receive) operation, @@ -36,7 +37,7 @@ func peers(o *Oracle, qpos *QueryPos) (queryResult, error) { // Look at all send/receive instructions in the whole ssa.Program. // Build a list of those of same type to query. - allFuncs := ssa.AllFunctions(o.prog) + allFuncs := ssautil.AllFunctions(o.prog) for fn := range allFuncs { for _, b := range fn.Blocks { for _, instr := range b.Instrs { diff --git a/ssa/doc.go b/ssa/doc.go index 0419f980cb4..7a873d4855f 100644 --- a/ssa/doc.go +++ b/ssa/doc.go @@ -114,14 +114,12 @@ // either accurate or unambiguous. The public API exposes a number of // name-based maps for client convenience. // +// The ssa/ssautil package provides various utilities that depend only +// on the public API of this package. +// // TODO(adonovan): Consider the exceptional control-flow implications // of defer and recover(). // -// TODO(adonovan): write an example showing how to visit all functions -// in a Program, including package init functions, methods of named -// and anon types, and functions used as values but never called -// directly. See AllFunctions(). -// // TODO(adonovan): write a how-to document for all the various cases // of trying to determine corresponding elements across the four // domains of source locations, ast.Nodes, types.Objects, diff --git a/ssa/visit.go b/ssa/ssautil/visit.go similarity index 76% rename from ssa/visit.go rename to ssa/ssautil/visit.go index 650821ae9b0..6cb51b4255f 100644 --- a/ssa/visit.go +++ b/ssa/ssautil/visit.go @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package ssa +package ssautil + +import "code.google.com/p/go.tools/ssa" // This file defines utilities for visiting the SSA representation of // a Program. @@ -17,24 +19,24 @@ package ssa // // Precondition: all packages are built. // -func AllFunctions(prog *Program) map[*Function]bool { +func AllFunctions(prog *ssa.Program) map[*ssa.Function]bool { visit := visitor{ prog: prog, - seen: make(map[*Function]bool), + seen: make(map[*ssa.Function]bool), } visit.program() return visit.seen } type visitor struct { - prog *Program - seen map[*Function]bool + prog *ssa.Program + seen map[*ssa.Function]bool } func (visit *visitor) program() { for _, pkg := range visit.prog.AllPackages() { for _, mem := range pkg.Members { - if fn, ok := mem.(*Function); ok { + if fn, ok := mem.(*ssa.Function); ok { visit.function(fn) } } @@ -47,14 +49,14 @@ func (visit *visitor) program() { } } -func (visit *visitor) function(fn *Function) { +func (visit *visitor) function(fn *ssa.Function) { if !visit.seen[fn] { visit.seen[fn] = true + var buf [10]*ssa.Value // avoid alloc in common case for _, b := range fn.Blocks { for _, instr := range b.Instrs { - var buf [10]*Value // avoid alloc in common case for _, op := range instr.Operands(buf[:0]) { - if fn, ok := (*op).(*Function); ok { + if fn, ok := (*op).(*ssa.Function); ok { visit.function(fn) } } diff --git a/ssa/stdlib_test.go b/ssa/stdlib_test.go index 51d0280b6ed..908ad47bbaf 100644 --- a/ssa/stdlib_test.go +++ b/ssa/stdlib_test.go @@ -21,6 +21,7 @@ import ( "code.google.com/p/go.tools/importer" "code.google.com/p/go.tools/ssa" + "code.google.com/p/go.tools/ssa/ssautil" ) const debugMode = false @@ -97,7 +98,7 @@ func TestStdlib(t *testing.T) { } // Dump some statistics. - allFuncs := ssa.AllFunctions(prog) + allFuncs := ssautil.AllFunctions(prog) var numInstrs int for fn := range allFuncs { for _, b := range fn.Blocks {