type VarAndLoop … // ForCapture transforms for and range loops that declare variables that might be // captured by a closure or escaped to the heap, using a syntactic check that // conservatively overestimates the loops where capture occurs, but still avoids // transforming the (large) majority of loops. It returns the list of names // subject to this change, that may (once transformed) be heap allocated in the // process. (This allows checking after escape analysis to call out any such // variables, in case it causes allocation/performance problems). // // The decision to transform loops is normally encoded in the For/Range loop node // field DistinctVars but is also dependent on base.LoopVarHash, and some values // of base.Debug.LoopVar (which is set per-package). Decisions encoded in DistinctVars // are preserved across inlining, so if package a calls b.F and loops in b.F are // transformed, then they are always transformed, whether b.F is inlined or not. // // Per-package, the debug flag settings that affect this transformer: // // base.LoopVarHash != nil => use hash setting to govern transformation. // note that LoopVarHash != nil sets base.Debug.LoopVar to 1 (unless it is >= 11, for testing/debugging). // // base.Debug.LoopVar == 11 => transform ALL loops ignoring syntactic/potential escape. Do not log, can be in addition to GOEXPERIMENT. // // The effect of GOEXPERIMENT=loopvar is to change the default value (0) of base.Debug.LoopVar to 1 for all packages. func ForCapture(fn *ir.Func) []VarAndLoop { … } // forAllDefInInitUpdate applies "do" to all the defining assignments in the Init clause of a ForStmt. // This abstracts away some of the boilerplate from the already complex and verbose for-3-clause case. func forAllDefInInitUpdate(x *ir.ForStmt, do func(z ir.Node, update *ir.Node)) { … } // forAllDefInInit is forAllDefInInitUpdate without the update option. func forAllDefInInit(x *ir.ForStmt, do func(z ir.Node)) { … } // rewriteNodes applies editNodes to all statement lists in fn. func rewriteNodes(fn *ir.Func, editNodes func(c ir.Nodes) ir.Nodes) { … } func LogTransformations(transformed []VarAndLoop) { … }