_linters/src/honnef.co/go/tools/ssa/builder.go
func (b *builder) forStmt(fn *Function, s *ast.ForStmt, label *lblock) {
	//	...init...
	//      jump loop
	// loop:
	//      if cond goto body else done
	// body:
	//      ...body...
	//      jump post
	// post:				 (target of continue)
	//      ...post...
	//      jump loop
	// done:                                 (target of break)
	if s.Init != nil {
		b.stmt(fn, s.Init)
	}
	body := fn.newBasicBlock("for.body")
	done := fn.newBasicBlock("for.done") // target of 'break'
	loop := body                         // target of back-edge
	if s.Cond != nil {
		loop = fn.newBasicBlock("for.loop")
	}
	cont := loop // target of 'continue'
	if s.Post != nil {
		cont = fn.newBasicBlock("for.post")
	}
	if label != nil {
		label._break = done
		label._continue = cont
	}
	emitJump(fn, loop)
	fn.currentBlock = loop
	if loop != body {
		b.cond(fn, s.Cond, body, done)
		fn.currentBlock = body
	}
	fn.targets = &targets{
		tail:      fn.targets,
		_break:    done,
		_continue: cont,
	}
	b.stmt(fn, s.Body)
	fn.targets = fn.targets.tail
	emitJump(fn, cont)

	if s.Post != nil {
		fn.currentBlock = cont
		b.stmt(fn, s.Post)
		emitJump(fn, loop) // back-edge
	}
	fn.currentBlock = done
}
func (b *builder) forStmt(fn *Function, s *ast.ForStmt, label *lblock) {
	//	...init...
	//      jump loop
	// loop:
	//      if cond goto body else done
	// body:
	//      ...body...
	//      jump post
	// post:				 (target of continue)
	//      ...post...
	//      jump loop
	// done:                                 (target of break)
	if s.Init != nil {
		b.stmt(fn, s.Init)
	}
	body := fn.newBasicBlock("for.body")
	done := fn.newBasicBlock("for.done") // target of 'break'
	loop := body                         // target of back-edge
	if s.Cond != nil {
		loop = fn.newBasicBlock("for.loop")
	}
	cont := loop // target of 'continue'
	if s.Post != nil {
		cont = fn.newBasicBlock("for.post")
	}
	if label != nil {
		label._break = done
		label._continue = cont
	}
	emitJump(fn, loop)
	fn.currentBlock = loop
	if loop != body {
		b.cond(fn, s.Cond, body, done)
		fn.currentBlock = body
	}
	fn.targets = &targets{
		tail:      fn.targets,
		_break:    done,
		_continue: cont,
	}
	b.stmt(fn, s.Body)
	fn.targets = fn.targets.tail
	emitJump(fn, cont)

	if s.Post != nil {
		fn.currentBlock = cont
		b.stmt(fn, s.Post)
		emitJump(fn, loop) // back-edge
	}
	fn.currentBlock = done
}
func ( b * builder ) forStmt ( fn * Function , s * ast . ForStmt , label * lblock ) { //	...init... //      jump loop // loop: //      if cond goto body else done // body: //      ...body... //      jump post // post:				 (target of continue) //      ...post... //      jump loop // done:                                 (target of break) if s . Init != nil { b . stmt ( fn , s . Init ) } body := fn . newBasicBlock ( " " ) done := fn . newBasicBlock ( " " ) // target of 'break' loop := body // target of back-edge if s . Cond != nil { loop = fn . newBasicBlock ( " " ) } cont := loop // target of 'continue' if s . Post != nil { cont = fn . newBasicBlock ( " " ) } if label != nil { label . _break = done label . _continue = cont } emitJump ( fn , loop ) fn . currentBlock = loop if loop != body { b . cond ( fn , s . Cond , body , done ) fn . currentBlock = body } fn . targets = & targets { tail : fn . targets , _break : done , _continue : cont , } b . stmt ( fn , s . Body ) fn . targets = fn . targets . tail emitJump ( fn , cont ) if s . Post != nil { fn . currentBlock = cont b . stmt ( fn , s . Post ) emitJump ( fn , loop ) // back-edge } fn . currentBlock = done }
// forStmt emits to fn code for the for statement s, optionally
// labelled by label.
//
forStmt emits to fn code for the for statement s optionally labelled by label .