mirror of
https://github.com/golang/go
synced 2024-11-19 04:04:47 -07:00
109 lines
4.1 KiB
Go
109 lines
4.1 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 call defines the call graph abstraction and various algorithms
|
||
|
and utilities to operate on it. It does not provide a concrete
|
||
|
implementation but permits other analyses (such as pointer analyses or
|
||
|
Rapid Type Analysis) to expose their own call graphs in a
|
||
|
representation-independent manner.
|
||
|
|
||
|
A call graph is a labelled directed graph whose nodes represent
|
||
|
functions and whose edge labels represent syntactic function call
|
||
|
sites. The presence of a labelled edge (caller, site, callee)
|
||
|
indicates that caller may call callee at the specified call site.
|
||
|
|
||
|
A call graph is a multigraph: it may contain multiple edges (caller,
|
||
|
*, callee) connecting the same pair of nodes, so long as the edges
|
||
|
differ by label; this occurs when one function calls another function
|
||
|
from multiple call sites. Also, it may contain multiple edges
|
||
|
(caller, site, *) that differ only by callee; this indicates a
|
||
|
polymorphic call.
|
||
|
|
||
|
A call graph is called CONTEXT INSENSITIVE if no two nodes in N
|
||
|
represent the same syntactic function declaration, i.e. the set of
|
||
|
nodes and the set of syntactic functions are in one-to-one
|
||
|
correspondence.
|
||
|
|
||
|
A context-sensitive call graph may have multiple nodes corresponding
|
||
|
to the same function; this may yield a more precise approximation to
|
||
|
the calling behavior of the program. Consider this program:
|
||
|
|
||
|
func Apply(fn func(V), value V) { fn(value) }
|
||
|
Apply(F, v1)
|
||
|
...
|
||
|
Apply(G, v2)
|
||
|
|
||
|
A context-insensitive call graph would represent all calls to Apply by
|
||
|
the same node, so that node would have successors F and G. A
|
||
|
context-sensitive call graph might represent the first and second
|
||
|
calls to Apply by distinct nodes, so that the first would have
|
||
|
successor F and the second would have successor G. This is a more
|
||
|
precise representation of the possible behaviors of the program.
|
||
|
|
||
|
A SOUND call graph is one that overapproximates the dynamic calling
|
||
|
behaviors of the program in all possible executions. One call graph
|
||
|
is more PRECISE than another if it is a smaller overapproximation of
|
||
|
the dynamic behavior.
|
||
|
|
||
|
All call graphs have a synthetic root node which is responsible for
|
||
|
calling main() and init().
|
||
|
|
||
|
Calls to built-in functions (e.g. panic, println) are not represented
|
||
|
in the call graph; they are treated like built-in operators of the
|
||
|
language.
|
||
|
|
||
|
*/
|
||
|
package call
|
||
|
|
||
|
import "code.google.com/p/go.tools/ssa"
|
||
|
|
||
|
// A Graph represents a call graph.
|
||
|
//
|
||
|
// A graph may contain nodes that are not reachable from the root.
|
||
|
// If the call graph is sound, such nodes indicate unreachable
|
||
|
// functions.
|
||
|
//
|
||
|
type Graph interface {
|
||
|
Root() GraphNode // the distinguished root node
|
||
|
Nodes() []GraphNode // new unordered set of all nodes
|
||
|
}
|
||
|
|
||
|
// A GraphNode represents a node in a call graph.
|
||
|
//
|
||
|
// If the call graph is context sensitive, there may be multiple
|
||
|
// GraphNodes with the same Func(); the identity of the graph node
|
||
|
// indicates the context.
|
||
|
//
|
||
|
// Sites returns the set of syntactic call sites within this function.
|
||
|
//
|
||
|
// For nodes representing synthetic or intrinsic functions
|
||
|
// (e.g. reflect.Call, or the root of the call graph), Sites() returns
|
||
|
// a slice containing a single nil value to indicate the synthetic
|
||
|
// call site, and each edge in Edges() has a nil Site.
|
||
|
//
|
||
|
// All nodes "belong" to a single graph and must not be mixed with
|
||
|
// nodes belonging to another graph.
|
||
|
//
|
||
|
// A site may appear in Sites() but not in {e.Site | e ∈ Edges()}.
|
||
|
// This indicates that that caller node was unreachable, or that the
|
||
|
// call was dynamic yet no func or interface values flow to the call
|
||
|
// site.
|
||
|
//
|
||
|
// Clients should not mutate the node via the results of its methods.
|
||
|
//
|
||
|
type GraphNode interface {
|
||
|
Func() *ssa.Function // the function this node represents
|
||
|
Sites() []ssa.CallInstruction // new unordered set of call sites within this function
|
||
|
Edges() []Edge // new unordered set of outgoing edges
|
||
|
}
|
||
|
|
||
|
// A Edge represents an edge in the call graph.
|
||
|
type Edge struct {
|
||
|
Caller GraphNode
|
||
|
Site ssa.CallInstruction
|
||
|
Callee GraphNode
|
||
|
}
|