// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gc

import (
	"cmd/compile/internal/types"
	"fmt"
	"sort"
)

const (
	// expression switch
	switchKindExpr  = iota // switch a {...} or switch 5 {...}
	switchKindTrue         // switch true {...} or switch {...}
	switchKindFalse        // switch false {...}
)

const (
	binarySearchMin = 4 // minimum number of cases for binary search
	integerRangeMin = 2 // minimum size of integer ranges
)

// An exprSwitch walks an expression switch.
type exprSwitch struct {
	exprname *Node // node for the expression being switched on
	kind     int   // kind of switch statement (switchKind*)
}

// A typeSwitch walks a type switch.
type typeSwitch struct {
	hashname *Node // node for the hash of the type of the variable being switched on
	facename *Node // node for the concrete type of the variable being switched on
	okname   *Node // boolean node used for comma-ok type assertions
}

// A caseClause is a single case clause in a switch statement.
type caseClause struct {
	node    *Node  // points at case statement
	ordinal int    // position in switch
	hash    uint32 // hash of a type switch
	// isconst indicates whether this case clause is a constant,
	// for the purposes of the switch code generation.
	// For expression switches, that's generally literals (case 5:, not case x:).
	// For type switches, that's concrete types (case time.Time:), not interfaces (case io.Reader:).
	isconst bool
}

// caseClauses are all the case clauses in a switch statement.
type caseClauses struct {
	list   []caseClause // general cases
	defjmp *Node        // OGOTO for default case or OBREAK if no default case present
	niljmp *Node        // OGOTO for nil type case in a type switch
}

// typecheckswitch typechecks a switch statement.
func typecheckswitch(n *Node) {
	typecheckslice(n.Ninit.Slice(), Etop)

	var nilonly string
	var top int
	var t *types.Type

	if n.Left != nil && n.Left.Op == OTYPESW {
		// type switch
		top = Etype
		n.Left.Right = typecheck(n.Left.Right, Erv)
		t = n.Left.Right.Type
		if t != nil && !t.IsInterface() {
			yyerrorl(n.Pos, "cannot type switch on non-interface value %L", n.Left.Right)
		}
		if v := n.Left.Left; v != nil && !v.isBlank() && n.List.Len() == 0 {
			// We don't actually declare the type switch's guarded
			// declaration itself. So if there are no cases, we
			// won't notice that it went unused.
			yyerrorl(v.Pos, "%v declared and not used", v.Sym)
		}
	} else {
		// expression switch
		top = Erv
		if n.Left != nil {
			n.Left = typecheck(n.Left, Erv)
			n.Left = defaultlit(n.Left, nil)
			t = n.Left.Type
		} else {
			t = types.Types[TBOOL]
		}
		if t != nil {
			switch {
			case !okforeq[t.Etype]:
				yyerrorl(n.Pos, "cannot switch on %L", n.Left)
			case t.IsSlice():
				nilonly = "slice"
			case t.IsArray() && !IsComparable(t):
				yyerrorl(n.Pos, "cannot switch on %L", n.Left)
			case t.IsStruct():
				if f := IncomparableField(t); f != nil {
					yyerrorl(n.Pos, "cannot switch on %L (struct containing %v cannot be compared)", n.Left, f.Type)
				}
			case t.Etype == TFUNC:
				nilonly = "func"
			case t.IsMap():
				nilonly = "map"
			}
		}
	}

	n.Type = t

	var def, niltype *Node
	for _, ncase := range n.List.Slice() {
		if ncase.List.Len() == 0 {
			// default
			if def != nil {
				setlineno(ncase)
				yyerrorl(ncase.Pos, "multiple defaults in switch (first at %v)", def.Line())
			} else {
				def = ncase
			}
		} else {
			ls := ncase.List.Slice()
			for i1, n1 := range ls {
				setlineno(n1)
				ls[i1] = typecheck(ls[i1], Erv|Etype)
				n1 = ls[i1]
				if n1.Type == nil || t == nil {
					continue
				}

				setlineno(ncase)
				switch top {
				// expression switch
				case Erv:
					ls[i1] = defaultlit(ls[i1], t)
					n1 = ls[i1]
					switch {
					case n1.Op == OTYPE:
						yyerrorl(ncase.Pos, "type %v is not an expression", n1.Type)
					case n1.Type != nil && assignop(n1.Type, t, nil) == 0 && assignop(t, n1.Type, nil) == 0:
						if n.Left != nil {
							yyerrorl(ncase.Pos, "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left, n1.Type, t)
						} else {
							yyerrorl(ncase.Pos, "invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type)
						}
					case nilonly != "" && !n1.isNil():
						yyerrorl(ncase.Pos, "invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left)
					case t.IsInterface() && !n1.Type.IsInterface() && !IsComparable(n1.Type):
						yyerrorl(ncase.Pos, "invalid case %L in switch (incomparable type)", n1)
					}

				// type switch
				case Etype:
					var missing, have *types.Field
					var ptr int
					switch {
					case n1.Op == OLITERAL && n1.Type.IsKind(TNIL):
						// case nil:
						if niltype != nil {
							yyerrorl(ncase.Pos, "multiple nil cases in type switch (first at %v)", niltype.Line())
						} else {
							niltype = ncase
						}
					case n1.Op != OTYPE && n1.Type != nil: // should this be ||?
						yyerrorl(ncase.Pos, "%L is not a type", n1)
						// reset to original type
						n1 = n.Left.Right
						ls[i1] = n1
					case !n1.Type.IsInterface() && t.IsInterface() && !implements(n1.Type, t, &missing, &have, &ptr):
						if have != nil && !missing.Broke() && !have.Broke() {
							yyerrorl(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
								" (wrong type for %v method)\n\thave %v%S\n\twant %v%S", n.Left.Right, n1.Type, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
						} else if !missing.Broke() {
							if ptr != 0 {
								yyerrorl(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
									" (%v method has pointer receiver)", n.Left.Right, n1.Type, missing.Sym)
							} else {
								yyerrorl(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
									" (missing %v method)", n.Left.Right, n1.Type, missing.Sym)
							}
						}
					}
				}
			}
		}

		if n.Type == nil || n.Type.IsUntyped() {
			// if the value we're switching on has no type or is untyped,
			// we've already printed an error and don't need to continue
			// typechecking the body
			return
		}

		if top == Etype {
			ll := ncase.List
			if ncase.Rlist.Len() != 0 {
				nvar := ncase.Rlist.First()
				if ll.Len() == 1 && ll.First().Type != nil && !ll.First().Type.IsKind(TNIL) {
					// single entry type switch
					nvar.Type = ll.First().Type
				} else {
					// multiple entry type switch or default
					nvar.Type = n.Type
				}

				nvar = typecheck(nvar, Erv|Easgn)
				ncase.Rlist.SetFirst(nvar)
			}
		}

		typecheckslice(ncase.Nbody.Slice(), Etop)
	}
	switch top {
	// expression switch
	case Erv:
		checkDupExprCases(n.Left, n.List.Slice())
	}
}

// walkswitch walks a switch statement.
func walkswitch(sw *Node) {
	// convert switch {...} to switch true {...}
	if sw.Left == nil {
		sw.Left = nodbool(true)
		sw.Left = typecheck(sw.Left, Erv)
		sw.Left = defaultlit(sw.Left, nil)
	}

	if sw.Left.Op == OTYPESW {
		var s typeSwitch
		s.walk(sw)
	} else {
		var s exprSwitch
		s.walk(sw)
	}
}

// walk generates an AST implementing sw.
// sw is an expression switch.
// The AST is generally of the form of a linear
// search using if..goto, although binary search
// is used with long runs of constants.
func (s *exprSwitch) walk(sw *Node) {
	// Guard against double walk, see #25776.
	if sw.List.Len() == 0 && sw.Nbody.Len() > 0 {
		Fatalf("second walk of switch")
	}

	casebody(sw, nil)

	cond := sw.Left
	sw.Left = nil

	s.kind = switchKindExpr
	if Isconst(cond, CTBOOL) {
		s.kind = switchKindTrue
		if !cond.Val().U.(bool) {
			s.kind = switchKindFalse
		}
	}

	// Given "switch string(byteslice)",
	// with all cases being constants (or the default case),
	// use a zero-cost alias of the byte slice.
	// In theory, we could be more aggressive,
	// allowing any side-effect-free expressions in cases,
	// but it's a bit tricky because some of that information
	// is unavailable due to the introduction of temporaries during order.
	// Restricting to constants is simple and probably powerful enough.
	// Do this before calling walkexpr on cond,
	// because walkexpr will lower the string
	// conversion into a runtime call.
	// See issue 24937 for more discussion.
	if cond.Op == OARRAYBYTESTR {
		ok := true
		for _, cas := range sw.List.Slice() {
			if cas.Op != OCASE {
				Fatalf("switch string(byteslice) bad op: %v", cas.Op)
			}
			if cas.Left != nil && !Isconst(cas.Left, CTSTR) {
				ok = false
				break
			}
		}
		if ok {
			cond.Op = OARRAYBYTESTRTMP
		}
	}

	cond = walkexpr(cond, &sw.Ninit)
	t := sw.Type
	if t == nil {
		return
	}

	// convert the switch into OIF statements
	var cas []*Node
	if s.kind == switchKindTrue || s.kind == switchKindFalse {
		s.exprname = nodbool(s.kind == switchKindTrue)
	} else if consttype(cond) > 0 {
		// leave constants to enable dead code elimination (issue 9608)
		s.exprname = cond
	} else {
		s.exprname = temp(cond.Type)
		cas = []*Node{nod(OAS, s.exprname, cond)}
		typecheckslice(cas, Etop)
	}

	// Enumerate the cases and prepare the default case.
	clauses := s.genCaseClauses(sw.List.Slice())
	sw.List.Set(nil)
	cc := clauses.list

	// handle the cases in order
	for len(cc) > 0 {
		run := 1
		if okforcmp[t.Etype] && cc[0].isconst {
			// do binary search on runs of constants
			for ; run < len(cc) && cc[run].isconst; run++ {
			}
			// sort and compile constants
			sort.Sort(caseClauseByConstVal(cc[:run]))
		}

		a := s.walkCases(cc[:run])
		cas = append(cas, a)
		cc = cc[run:]
	}

	// handle default case
	if nerrors == 0 {
		cas = append(cas, clauses.defjmp)
		sw.Nbody.Prepend(cas...)
		walkstmtlist(sw.Nbody.Slice())
	}
}

// walkCases generates an AST implementing the cases in cc.
func (s *exprSwitch) walkCases(cc []caseClause) *Node {
	if len(cc) < binarySearchMin {
		// linear search
		var cas []*Node
		for _, c := range cc {
			n := c.node
			lno := setlineno(n)

			a := nod(OIF, nil, nil)
			if rng := n.List.Slice(); rng != nil {
				// Integer range.
				// exprname is a temp or a constant,
				// so it is safe to evaluate twice.
				// In most cases, this conjunction will be
				// rewritten by walkinrange into a single comparison.
				low := nod(OGE, s.exprname, rng[0])
				high := nod(OLE, s.exprname, rng[1])
				a.Left = nod(OANDAND, low, high)
			} else if (s.kind != switchKindTrue && s.kind != switchKindFalse) || assignop(n.Left.Type, s.exprname.Type, nil) == OCONVIFACE || assignop(s.exprname.Type, n.Left.Type, nil) == OCONVIFACE {
				a.Left = nod(OEQ, s.exprname, n.Left) // if name == val
			} else if s.kind == switchKindTrue {
				a.Left = n.Left // if val
			} else {
				// s.kind == switchKindFalse
				a.Left = nod(ONOT, n.Left, nil) // if !val
			}
			a.Left = typecheck(a.Left, Erv)
			a.Left = defaultlit(a.Left, nil)
			a.Nbody.Set1(n.Right) // goto l

			cas = append(cas, a)
			lineno = lno
		}
		return liststmt(cas)
	}

	// find the middle and recur
	half := len(cc) / 2
	a := nod(OIF, nil, nil)
	n := cc[half-1].node
	var mid *Node
	if rng := n.List.Slice(); rng != nil {
		mid = rng[1] // high end of range
	} else {
		mid = n.Left
	}
	le := nod(OLE, s.exprname, mid)
	if Isconst(mid, CTSTR) {
		// Search by length and then by value; see caseClauseByConstVal.
		lenlt := nod(OLT, nod(OLEN, s.exprname, nil), nod(OLEN, mid, nil))
		leneq := nod(OEQ, nod(OLEN, s.exprname, nil), nod(OLEN, mid, nil))
		a.Left = nod(OOROR, lenlt, nod(OANDAND, leneq, le))
	} else {
		a.Left = le
	}
	a.Left = typecheck(a.Left, Erv)
	a.Left = defaultlit(a.Left, nil)
	a.Nbody.Set1(s.walkCases(cc[:half]))
	a.Rlist.Set1(s.walkCases(cc[half:]))
	return a
}

// casebody builds separate lists of statements and cases.
// It makes labels between cases and statements
// and deals with fallthrough, break, and unreachable statements.
func casebody(sw *Node, typeswvar *Node) {
	if sw.List.Len() == 0 {
		return
	}

	lno := setlineno(sw)

	var cas []*Node  // cases
	var stat []*Node // statements
	var def *Node    // defaults
	br := nod(OBREAK, nil, nil)

	for _, n := range sw.List.Slice() {
		setlineno(n)
		if n.Op != OXCASE {
			Fatalf("casebody %v", n.Op)
		}
		n.Op = OCASE
		needvar := n.List.Len() != 1 || n.List.First().Op == OLITERAL

		jmp := nod(OGOTO, autolabel(".s"), nil)
		switch n.List.Len() {
		case 0:
			// default
			if def != nil {
				yyerrorl(n.Pos, "more than one default case")
			}
			// reuse original default case
			n.Right = jmp
			def = n
		case 1:
			// one case -- reuse OCASE node
			n.Left = n.List.First()
			n.Right = jmp
			n.List.Set(nil)
			cas = append(cas, n)
		default:
			// Expand multi-valued cases and detect ranges of integer cases.
			if typeswvar != nil || sw.Left.Type.IsInterface() || !n.List.First().Type.IsInteger() || n.List.Len() < integerRangeMin {
				// Can't use integer ranges. Expand each case into a separate node.
				for _, n1 := range n.List.Slice() {
					cas = append(cas, nod(OCASE, n1, jmp))
				}
				break
			}
			// Find integer ranges within runs of constants.
			s := n.List.Slice()
			j := 0
			for j < len(s) {
				// Find a run of constants.
				var run int
				for run = j; run < len(s) && Isconst(s[run], CTINT); run++ {
				}
				if run-j >= integerRangeMin {
					// Search for integer ranges in s[j:run].
					// Typechecking is done, so all values are already in an appropriate range.
					search := s[j:run]
					sort.Sort(constIntNodesByVal(search))
					for beg, end := 0, 1; end <= len(search); end++ {
						if end < len(search) && search[end].Int64() == search[end-1].Int64()+1 {
							continue
						}
						if end-beg >= integerRangeMin {
							// Record range in List.
							c := nod(OCASE, nil, jmp)
							c.List.Set2(search[beg], search[end-1])
							cas = append(cas, c)
						} else {
							// Not large enough for range; record separately.
							for _, n := range search[beg:end] {
								cas = append(cas, nod(OCASE, n, jmp))
							}
						}
						beg = end
					}
					j = run
				}
				// Advance to next constant, adding individual non-constant
				// or as-yet-unhandled constant cases as we go.
				for ; j < len(s) && (j < run || !Isconst(s[j], CTINT)); j++ {
					cas = append(cas, nod(OCASE, s[j], jmp))
				}
			}
		}

		stat = append(stat, nod(OLABEL, jmp.Left, nil))
		if typeswvar != nil && needvar && n.Rlist.Len() != 0 {
			l := []*Node{
				nod(ODCL, n.Rlist.First(), nil),
				nod(OAS, n.Rlist.First(), typeswvar),
			}
			typecheckslice(l, Etop)
			stat = append(stat, l...)
		}
		stat = append(stat, n.Nbody.Slice()...)

		// Search backwards for the index of the fallthrough
		// statement. Do not assume it'll be in the last
		// position, since in some cases (e.g. when the statement
		// list contains autotmp_ variables), one or more OVARKILL
		// nodes will be at the end of the list.
		fallIndex := len(stat) - 1
		for stat[fallIndex].Op == OVARKILL {
			fallIndex--
		}
		last := stat[fallIndex]
		if last.Op != OFALL {
			stat = append(stat, br)
		}
	}

	stat = append(stat, br)
	if def != nil {
		cas = append(cas, def)
	}

	sw.List.Set(cas)
	sw.Nbody.Set(stat)
	lineno = lno
}

// genCaseClauses generates the caseClauses value for clauses.
func (s *exprSwitch) genCaseClauses(clauses []*Node) caseClauses {
	var cc caseClauses
	for _, n := range clauses {
		if n.Left == nil && n.List.Len() == 0 {
			// default case
			if cc.defjmp != nil {
				Fatalf("duplicate default case not detected during typechecking")
			}
			cc.defjmp = n.Right
			continue
		}
		c := caseClause{node: n, ordinal: len(cc.list)}
		if n.List.Len() > 0 {
			c.isconst = true
		}
		switch consttype(n.Left) {
		case CTFLT, CTINT, CTRUNE, CTSTR:
			c.isconst = true
		}
		cc.list = append(cc.list, c)
	}

	if cc.defjmp == nil {
		cc.defjmp = nod(OBREAK, nil, nil)
	}
	return cc
}

// genCaseClauses generates the caseClauses value for clauses.
func (s *typeSwitch) genCaseClauses(clauses []*Node) caseClauses {
	var cc caseClauses
	for _, n := range clauses {
		switch {
		case n.Left == nil:
			// default case
			if cc.defjmp != nil {
				Fatalf("duplicate default case not detected during typechecking")
			}
			cc.defjmp = n.Right
			continue
		case n.Left.Op == OLITERAL:
			// nil case in type switch
			if cc.niljmp != nil {
				Fatalf("duplicate nil case not detected during typechecking")
			}
			cc.niljmp = n.Right
			continue
		}

		// general case
		c := caseClause{
			node:    n,
			ordinal: len(cc.list),
			isconst: !n.Left.Type.IsInterface(),
			hash:    typehash(n.Left.Type),
		}
		cc.list = append(cc.list, c)
	}

	if cc.defjmp == nil {
		cc.defjmp = nod(OBREAK, nil, nil)
	}

	// diagnose duplicate cases
	s.checkDupCases(cc.list)
	return cc
}

func (s *typeSwitch) checkDupCases(cc []caseClause) {
	if len(cc) < 2 {
		return
	}
	// We store seen types in a map keyed by type hash.
	// It is possible, but very unlikely, for multiple distinct types to have the same hash.
	seen := make(map[uint32][]*Node)
	// To avoid many small allocations of length 1 slices,
	// also set up a single large slice to slice into.
	nn := make([]*Node, 0, len(cc))
Outer:
	for _, c := range cc {
		prev, ok := seen[c.hash]
		if !ok {
			// First entry for this hash.
			nn = append(nn, c.node)
			seen[c.hash] = nn[len(nn)-1 : len(nn) : len(nn)]
			continue
		}
		for _, n := range prev {
			if eqtype(n.Left.Type, c.node.Left.Type) {
				yyerrorl(c.node.Pos, "duplicate case %v in type switch\n\tprevious case at %v", c.node.Left.Type, n.Line())
				// avoid double-reporting errors
				continue Outer
			}
		}
		seen[c.hash] = append(seen[c.hash], c.node)
	}
}

func checkDupExprCases(exprname *Node, clauses []*Node) {
	// boolean (naked) switch, nothing to do.
	if exprname == nil {
		return
	}
	// The common case is that s's expression is not an interface.
	// In that case, all constant clauses have the same type,
	// so checking for duplicates can be done solely by value.
	if !exprname.Type.IsInterface() {
		seen := make(map[interface{}]*Node)
		for _, ncase := range clauses {
			for _, n := range ncase.List.Slice() {
				// Can't check for duplicates that aren't constants, per the spec. Issue 15896.
				// Don't check for duplicate bools. Although the spec allows it,
				// (1) the compiler hasn't checked it in the past, so compatibility mandates it, and
				// (2) it would disallow useful things like
				//       case GOARCH == "arm" && GOARM == "5":
				//       case GOARCH == "arm":
				//     which would both evaluate to false for non-ARM compiles.
				if ct := consttype(n); ct == 0 || ct == CTBOOL {
					continue
				}

				val := n.Val().Interface()
				prev, dup := seen[val]
				if !dup {
					seen[val] = n
					continue
				}
				yyerrorl(ncase.Pos, "duplicate case %s in switch\n\tprevious case at %v",
					nodeAndVal(n), prev.Line())
			}
		}
		return
	}

	// s's expression is an interface. This is fairly rare, so
	// keep this simple. Case expressions are only duplicates if
	// they have the same value and identical types.
	//
	// In general, we have to use eqtype to test type identity,
	// because == gives false negatives for anonymous types and
	// the byte/uint8 and rune/int32 builtin type aliases.
	// However, this is not a problem here, because constant
	// expressions are always untyped or have a named type, and we
	// explicitly handle the builtin type aliases below.
	//
	// This approach may need to be revisited though if we fix
	// #21866 by treating all type aliases like byte/uint8 and
	// rune/int32.
	type typeVal struct {
		typ *types.Type
		val interface{}
	}
	seen := make(map[typeVal]*Node)
	for _, ncase := range clauses {
		for _, n := range ncase.List.Slice() {
			if ct := consttype(n); ct == 0 || ct == CTBOOL {
				continue
			}
			tv := typeVal{
				typ: n.Type,
				val: n.Val().Interface(),
			}
			switch tv.typ {
			case types.Bytetype:
				tv.typ = types.Types[TUINT8]
			case types.Runetype:
				tv.typ = types.Types[TINT32]
			}
			prev, dup := seen[tv]
			if !dup {
				seen[tv] = n
				continue
			}
			yyerrorl(ncase.Pos, "duplicate case %s in switch\n\tprevious case at %v",
				nodeAndVal(n), prev.Line())
		}
	}
}

func nodeAndVal(n *Node) string {
	show := n.String()
	val := n.Val().Interface()
	if s := fmt.Sprintf("%#v", val); show != s {
		show += " (value " + s + ")"
	}
	return show
}

// walk generates an AST that implements sw,
// where sw is a type switch.
// The AST is generally of the form of a linear
// search using if..goto, although binary search
// is used with long runs of concrete types.
func (s *typeSwitch) walk(sw *Node) {
	cond := sw.Left
	sw.Left = nil

	if cond == nil {
		sw.List.Set(nil)
		return
	}
	if cond.Right == nil {
		yyerrorl(sw.Pos, "type switch must have an assignment")
		return
	}

	cond.Right = walkexpr(cond.Right, &sw.Ninit)
	if !cond.Right.Type.IsInterface() {
		yyerrorl(sw.Pos, "type switch must be on an interface")
		return
	}

	var cas []*Node

	// predeclare temporary variables and the boolean var
	s.facename = temp(cond.Right.Type)

	a := nod(OAS, s.facename, cond.Right)
	a = typecheck(a, Etop)
	cas = append(cas, a)

	s.okname = temp(types.Types[TBOOL])
	s.okname = typecheck(s.okname, Erv)

	s.hashname = temp(types.Types[TUINT32])
	s.hashname = typecheck(s.hashname, Erv)

	// set up labels and jumps
	casebody(sw, s.facename)

	clauses := s.genCaseClauses(sw.List.Slice())
	sw.List.Set(nil)
	def := clauses.defjmp

	// For empty interfaces, do:
	//     if e._type == nil {
	//         do nil case if it exists, otherwise default
	//     }
	//     h := e._type.hash
	// Use a similar strategy for non-empty interfaces.

	// Get interface descriptor word.
	// For empty interfaces this will be the type.
	// For non-empty interfaces this will be the itab.
	itab := nod(OITAB, s.facename, nil)

	// Check for nil first.
	i := nod(OIF, nil, nil)
	i.Left = nod(OEQ, itab, nodnil())
	if clauses.niljmp != nil {
		// Do explicit nil case right here.
		i.Nbody.Set1(clauses.niljmp)
	} else {
		// Jump to default case.
		lbl := autolabel(".s")
		i.Nbody.Set1(nod(OGOTO, lbl, nil))
		// Wrap default case with label.
		blk := nod(OBLOCK, nil, nil)
		blk.List.Set2(nod(OLABEL, lbl, nil), def)
		def = blk
	}
	i.Left = typecheck(i.Left, Erv)
	i.Left = defaultlit(i.Left, nil)
	cas = append(cas, i)

	// Load hash from type or itab.
	h := nodSym(ODOTPTR, itab, nil)
	h.Type = types.Types[TUINT32]
	h.SetTypecheck(1)
	if cond.Right.Type.IsEmptyInterface() {
		h.Xoffset = int64(2 * Widthptr) // offset of hash in runtime._type
	} else {
		h.Xoffset = int64(2 * Widthptr) // offset of hash in runtime.itab
	}
	h.SetBounded(true) // guaranteed not to fault
	a = nod(OAS, s.hashname, h)
	a = typecheck(a, Etop)
	cas = append(cas, a)

	cc := clauses.list

	// insert type equality check into each case block
	for _, c := range cc {
		c.node.Right = s.typeone(c.node)
	}

	// generate list of if statements, binary search for constant sequences
	for len(cc) > 0 {
		if !cc[0].isconst {
			n := cc[0].node
			cas = append(cas, n.Right)
			cc = cc[1:]
			continue
		}

		// identify run of constants
		var run int
		for run = 1; run < len(cc) && cc[run].isconst; run++ {
		}

		// sort by hash
		sort.Sort(caseClauseByType(cc[:run]))

		// for debugging: linear search
		if false {
			for i := 0; i < run; i++ {
				n := cc[i].node
				cas = append(cas, n.Right)
			}
			continue
		}

		// combine adjacent cases with the same hash
		var batch []caseClause
		for i, j := 0, 0; i < run; i = j {
			hash := []*Node{cc[i].node.Right}
			for j = i + 1; j < run && cc[i].hash == cc[j].hash; j++ {
				hash = append(hash, cc[j].node.Right)
			}
			cc[i].node.Right = liststmt(hash)
			batch = append(batch, cc[i])
		}

		// binary search among cases to narrow by hash
		cas = append(cas, s.walkCases(batch))
		cc = cc[run:]
	}

	// handle default case
	if nerrors == 0 {
		cas = append(cas, def)
		sw.Nbody.Prepend(cas...)
		sw.List.Set(nil)
		walkstmtlist(sw.Nbody.Slice())
	}
}

// typeone generates an AST that jumps to the
// case body if the variable is of type t.
func (s *typeSwitch) typeone(t *Node) *Node {
	var name *Node
	var init Nodes
	if t.Rlist.Len() == 0 {
		name = nblank
		nblank = typecheck(nblank, Erv|Easgn)
	} else {
		name = t.Rlist.First()
		init.Append(nod(ODCL, name, nil))
		a := nod(OAS, name, nil)
		a = typecheck(a, Etop)
		init.Append(a)
	}

	a := nod(OAS2, nil, nil)
	a.List.Set2(name, s.okname) // name, ok =
	b := nod(ODOTTYPE, s.facename, nil)
	b.Type = t.Left.Type // interface.(type)
	a.Rlist.Set1(b)
	a = typecheck(a, Etop)
	a = walkexpr(a, &init)
	init.Append(a)

	c := nod(OIF, nil, nil)
	c.Left = s.okname
	c.Nbody.Set1(t.Right) // if ok { goto l }

	init.Append(c)
	return init.asblock()
}

// walkCases generates an AST implementing the cases in cc.
func (s *typeSwitch) walkCases(cc []caseClause) *Node {
	if len(cc) < binarySearchMin {
		var cas []*Node
		for _, c := range cc {
			n := c.node
			if !c.isconst {
				Fatalf("typeSwitch walkCases")
			}
			a := nod(OIF, nil, nil)
			a.Left = nod(OEQ, s.hashname, nodintconst(int64(c.hash)))
			a.Left = typecheck(a.Left, Erv)
			a.Left = defaultlit(a.Left, nil)
			a.Nbody.Set1(n.Right)
			cas = append(cas, a)
		}
		return liststmt(cas)
	}

	// find the middle and recur
	half := len(cc) / 2
	a := nod(OIF, nil, nil)
	a.Left = nod(OLE, s.hashname, nodintconst(int64(cc[half-1].hash)))
	a.Left = typecheck(a.Left, Erv)
	a.Left = defaultlit(a.Left, nil)
	a.Nbody.Set1(s.walkCases(cc[:half]))
	a.Rlist.Set1(s.walkCases(cc[half:]))
	return a
}

// caseClauseByConstVal sorts clauses by constant value to enable binary search.
type caseClauseByConstVal []caseClause

func (x caseClauseByConstVal) Len() int      { return len(x) }
func (x caseClauseByConstVal) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x caseClauseByConstVal) Less(i, j int) bool {
	// n1 and n2 might be individual constants or integer ranges.
	// We have checked for duplicates already,
	// so ranges can be safely represented by any value in the range.
	n1 := x[i].node
	var v1 interface{}
	if s := n1.List.Slice(); s != nil {
		v1 = s[0].Val().U
	} else {
		v1 = n1.Left.Val().U
	}

	n2 := x[j].node
	var v2 interface{}
	if s := n2.List.Slice(); s != nil {
		v2 = s[0].Val().U
	} else {
		v2 = n2.Left.Val().U
	}

	switch v1 := v1.(type) {
	case *Mpflt:
		return v1.Cmp(v2.(*Mpflt)) < 0
	case *Mpint:
		return v1.Cmp(v2.(*Mpint)) < 0
	case string:
		// Sort strings by length and then by value.
		// It is much cheaper to compare lengths than values,
		// and all we need here is consistency.
		// We respect this sorting in exprSwitch.walkCases.
		a := v1
		b := v2.(string)
		if len(a) != len(b) {
			return len(a) < len(b)
		}
		return a < b
	}

	Fatalf("caseClauseByConstVal passed bad clauses %v < %v", x[i].node.Left, x[j].node.Left)
	return false
}

type caseClauseByType []caseClause

func (x caseClauseByType) Len() int      { return len(x) }
func (x caseClauseByType) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x caseClauseByType) Less(i, j int) bool {
	c1, c2 := x[i], x[j]
	// sort by hash code, then ordinal (for the rare case of hash collisions)
	if c1.hash != c2.hash {
		return c1.hash < c2.hash
	}
	return c1.ordinal < c2.ordinal
}

type constIntNodesByVal []*Node

func (x constIntNodesByVal) Len() int      { return len(x) }
func (x constIntNodesByVal) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x constIntNodesByVal) Less(i, j int) bool {
	return x[i].Val().U.(*Mpint).Cmp(x[j].Val().U.(*Mpint)) < 0
}
