gotools/go/callgraph/vta/graph.go

type node

type constant

func (c constant) Type() types.Type {}

func (c constant) String() string {}

type pointer

func (p pointer) Type() types.Type {}

func (p pointer) String() string {}

type mapKey

func (mk mapKey) Type() types.Type {}

func (mk mapKey) String() string {}

type mapValue

func (mv mapValue) Type() types.Type {}

func (mv mapValue) String() string {}

type sliceElem

func (s sliceElem) Type() types.Type {}

func (s sliceElem) String() string {}

type channelElem

func (c channelElem) Type() types.Type {}

func (c channelElem) String() string {}

type field

func (f field) Type() types.Type {}

func (f field) String() string {}

type global

func (g global) Type() types.Type {}

func (g global) String() string {}

type local

func (l local) Type() types.Type {}

func (l local) String() string {}

type indexedLocal

func (i indexedLocal) Type() types.Type {}

func (i indexedLocal) String() string {}

type function

func (f function) Type() types.Type {}

func (f function) String() string {}

type resultVar

func (o resultVar) Type() types.Type {}

func (o resultVar) String() string {}

type nestedPtrInterface

func (l nestedPtrInterface) Type() types.Type {}

func (l nestedPtrInterface) String() string {}

type nestedPtrFunction

func (p nestedPtrFunction) Type() types.Type {}

func (p nestedPtrFunction) String() string {}

type panicArg

func (p panicArg) Type() types.Type {}

func (p panicArg) String() string {}

type recoverReturn

func (r recoverReturn) Type() types.Type {}

func (r recoverReturn) String() string {}

type empty

type idx

type vtaGraph

func (g *vtaGraph) numNodes() int {}

func (g *vtaGraph) successors(x idx) func(yield func(y idx) bool) {}

// addEdge adds an edge x->y to the graph.
func (g *vtaGraph) addEdge(x, y node) {}

// typePropGraph builds a VTA graph for a set of `funcs` and initial
// `callgraph` needed to establish interprocedural edges. Returns the
// graph and a map for unique type representatives.
func typePropGraph(funcs map[*ssa.Function]bool, callees calleesFunc) (*vtaGraph, *typeutil.Map) {}

type builder

func (b *builder) visit(funcs map[*ssa.Function]bool) {}

func (b *builder) fun(f *ssa.Function) {}

func (b *builder) instr(instr ssa.Instruction) {}

func (b *builder) unop(u *ssa.UnOp) {}

func (b *builder) phi(p *ssa.Phi) {}

func (b *builder) tassert(a *ssa.TypeAssert) {}

// extract instruction t1 := t2[i] generates flows between t2[i]
// and t1 where the source is indexed local representing a value
// from tuple register t2 at index i and the target is t1.
func (b *builder) extract(e *ssa.Extract) {}

func (b *builder) field(f *ssa.Field) {}

func (b *builder) fieldAddr(f *ssa.FieldAddr) {}

func (b *builder) send(s *ssa.Send) {}

// selekt generates flows for select statement
//
//	a = select blocking/nonblocking [c_1 <- t_1, c_2 <- t_2, ..., <- o_1, <- o_2, ...]
//
// between receiving channel registers c_i and corresponding input register t_i. Further,
// flows are generated between o_i and a[2 + i]. Note that a is a tuple register of type
// <int, bool, r_1, r_2, ...> where the type of r_i is the element type of channel o_i.
func (b *builder) selekt(s *ssa.Select) {}

// index instruction a := b[c] on slices creates flows between a and
// SliceElem(t) flow where t is an interface type of c. Arrays and
// slice elements are both modeled as SliceElem.
func (b *builder) index(i *ssa.Index) {}

// indexAddr instruction a := &b[c] fetches address of a index
// into the field so we create bidirectional flow a <-> SliceElem(t)
// where t is an interface type of c. Arrays and slice elements are
// both modeled as SliceElem.
func (b *builder) indexAddr(i *ssa.IndexAddr) {}

// lookup handles map query commands a := m[b] where m is of type
// map[...]V and V is an interface. It creates flows between `a`
// and MapValue(V).
func (b *builder) lookup(l *ssa.Lookup) {}

// mapUpdate handles map update commands m[b] = a where m is of type
// map[K]V and K and V are interfaces. It creates flows between `a`
// and MapValue(V) as well as between MapKey(K) and `b`.
func (b *builder) mapUpdate(u *ssa.MapUpdate) {}

// next instruction <ok, key, value> := next r, where r
// is a range over map or string generates flow between
// key and MapKey as well value and MapValue nodes.
func (b *builder) next(n *ssa.Next) {}

// addInFlowAliasEdges adds an edge r -> l to b.graph if l is a node that can
// have an inflow, i.e., a node that represents an interface or an unresolved
// function value. Similarly for the edge l -> r with an additional condition
// of that l and r can potentially alias.
func (b *builder) addInFlowAliasEdges(l, r node) {}

func (b *builder) closure(c *ssa.MakeClosure) {}

// panic creates a flow from arguments to panic instructions to return
// registers of all recover statements in the program. Introduces a
// global panic node Panic and
//  1. for every panic statement p: add p -> Panic
//  2. for every recover statement r: add Panic -> r (handled in call)
//
// TODO(zpavlinovic): improve precision by explicitly modeling how panic
// values flow from callees to callers and into deferred recover instructions.
func (b *builder) panic(p *ssa.Panic) {}

// call adds flows between arguments/parameters and return values/registers
// for both static and dynamic calls, as well as go and defer calls.
func (b *builder) call(c ssa.CallInstruction) {}

func addArgumentFlows(b *builder, c ssa.CallInstruction, f *ssa.Function) {}

// rtrn creates flow edges from the operands of the return
// statement to the result variables of the enclosing function.
func (b *builder) rtrn(r *ssa.Return) {}

func (b *builder) multiconvert(c *ssa.MultiConvert) {}

// addInFlowEdge adds s -> d to g if d is node that can have an inflow, i.e., a node
// that represents an interface or an unresolved function value. Otherwise, there
// is no interesting type flow so the edge is omitted.
func (b *builder) addInFlowEdge(s, d node) {}

// Creates const, pointer, global, func, and local nodes based on register instructions.
func (b *builder) nodeFromVal(val ssa.Value) node {}

// representative returns a unique representative for node `n`. Since
// semantically equivalent types can have different implementations,
// this method guarantees the same implementation is always used.
func (b *builder) representative(n node) node {}

// canonicalize returns a type representative of `t` unique subject
// to type map `canon`.
func canonicalize(t types.Type, canon *typeutil.Map) types.Type {}