// genRootCalls generates the synthetic root of the callgraph and the // initial calls from it to the analysis scope, such as main, a test // or a library. // func (a *analysis) genRootCalls() *cgnode { r := ssa.NewFunction("<root>", new(types.Signature), "root of callgraph") r.Prog = a.prog // hack. r.Enclosing = r // hack, so Function.String() doesn't crash r.String() // (asserts that it doesn't crash) root := a.makeCGNode(r, 0, nil) // TODO(adonovan): make an ssa utility to construct an actual // root function so we don't need to special-case site-less // call edges. // For each main package, call main.init(), main.main(). for _, mainPkg := range a.config.Mains { main := mainPkg.Func("main") if main == nil { panic(fmt.Sprintf("%s has no main function", mainPkg)) } targets := a.addOneNode(main.Signature, "root.targets", nil) site := &callsite{targets: targets} root.sites = append(root.sites, site) for _, fn := range [2]*ssa.Function{mainPkg.Func("init"), main} { if a.log != nil { fmt.Fprintf(a.log, "\troot call to %s:\n", fn) } a.copy(targets, a.valueNode(fn), 1) } } return root }
// newMethod creates a new method of the specified name, package and receiver type. func newMethod(pkg *ssa.Package, recvType types.Type, name string) *ssa.Function { // TODO(adonovan): fix: hack: currently the only part of Signature // that is needed is the "pointerness" of Recv.Type, and for // now, we'll set it to always be false since we're only // concerned with rtype. Encapsulate this better. sig := types.NewSignature(nil, types.NewVar(token.NoPos, nil, "recv", recvType), nil, nil, false) fn := ssa.NewFunction(name, sig, "fake reflect method") fn.Pkg = pkg fn.Prog = pkg.Prog return fn }