// generate generates offline constraints for the entire program. func (a *analysis) generate() { start("Constraint generation") if a.log != nil { fmt.Fprintln(a.log, "==== Generating constraints") } // Create a dummy node since we use the nodeid 0 for // non-pointerlike variables. a.addNodes(tInvalid, "(zero)") // Create the global node for panic values. a.panicNode = a.addNodes(tEface, "panic") // Create nodes and constraints for all methods of reflect.rtype. // (Shared contours are used by dynamic calls to reflect.Type // methods---typically just String().) if rtype := a.reflectRtypePtr; rtype != nil { a.genMethodsOf(rtype) } root := a.genRootCalls() if a.config.BuildCallGraph { a.result.CallGraph = callgraph.New(root.fn) } // Create nodes and constraints for all methods of all types // that are dynamically accessible via reflection or interfaces. for _, T := range a.prog.RuntimeTypes() { a.genMethodsOf(T) } // Generate constraints for entire program. for len(a.genq) > 0 { cgn := a.genq[0] a.genq = a.genq[1:] a.genFunc(cgn) } // The runtime magically allocates os.Args; so should we. if os := a.prog.ImportedPackage("os"); os != nil { // In effect: os.Args = new([1]string)[:] T := types.NewSlice(types.Typ[types.String]) obj := a.addNodes(sliceToArray(T), "<command-line args>") a.endObject(obj, nil, "<command-line args>") a.addressOf(T, a.objectNode(nil, os.Var("Args")), obj) } // Discard generation state, to avoid confusion after node renumbering. a.panicNode = 0 a.globalval = nil a.localval = nil a.localobj = nil stop("Constraint generation") }
// createParams creates parameters for wrapper method fn based on its // Signature.Params, which do not include the receiver. // start is the index of the first regular parameter to use. // func createParams(fn *Function, start int) { var last *Parameter tparams := fn.Signature.Params() for i, n := start, tparams.Len(); i < n; i++ { last = fn.addParamObj(tparams.At(i)) } if fn.Signature.Variadic() { last.typ = types.NewSlice(last.typ) } }
func ext۰reflect۰SliceOf(fr *frame, args []value) value { // Signature: func (t reflect.rtype) Type return makeReflectType(rtype{types.NewSlice(args[0].(iface).v.(rtype).t)}) }