// 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/internal/obj"
	"fmt"
	"sort"
	"strconv"
)

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

	// type switch
	switchKindType // switch a.(type) {...}
)

const (
	caseKindDefault = iota // default:

	// expression switch
	caseKindExprConst // case 5:
	caseKindExprVar   // case x:

	// type switch
	caseKindTypeNil   // case nil:
	caseKindTypeConst // case time.Time: (concrete type, has type hash)
	caseKindTypeVar   // case io.Reader: (interface type)
)

const binarySearchMin = 4 // minimum number of cases for binary search

// 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
	typ     uint8  // type of case
}

// typecheckswitch typechecks a switch statement.
func typecheckswitch(n *Node) {
	lno := int(lineno)
	typechecklist(n.Ninit, Etop)

	var nilonly string
	var top int
	var t *Type

	if n.Left != nil && n.Left.Op == OTYPESW {
		// type switch
		top = Etype
		typecheck(&n.Left.Right, Erv)
		t = n.Left.Right.Type
		if t != nil && t.Etype != TINTER {
			Yyerror("cannot type switch on non-interface value %v", Nconv(n.Left.Right, obj.FmtLong))
		}
	} else {
		// expression switch
		top = Erv
		if n.Left != nil {
			typecheck(&n.Left, Erv)
			defaultlit(&n.Left, nil)
			t = n.Left.Type
		} else {
			t = Types[TBOOL]
		}
		if t != nil {
			var badtype *Type
			switch {
			case !okforeq[t.Etype]:
				Yyerror("cannot switch on %v", Nconv(n.Left, obj.FmtLong))
			case t.Etype == TARRAY && !Isfixedarray(t):
				nilonly = "slice"
			case t.Etype == TARRAY && Isfixedarray(t) && algtype1(t, nil) == ANOEQ:
				Yyerror("cannot switch on %v", Nconv(n.Left, obj.FmtLong))
			case t.Etype == TSTRUCT && algtype1(t, &badtype) == ANOEQ:
				Yyerror("cannot switch on %v (struct containing %v cannot be compared)", Nconv(n.Left, obj.FmtLong), badtype)
			case t.Etype == TFUNC:
				nilonly = "func"
			case t.Etype == TMAP:
				nilonly = "map"
			}
		}
	}

	n.Type = t

	var def *Node
	var ll *NodeList
	for l := n.List; l != nil; l = l.Next {
		ncase := l.N
		setlineno(n)
		if ncase.List == nil {
			// default
			if def != nil {
				Yyerror("multiple defaults in switch (first at %v)", def.Line())
			} else {
				def = ncase
			}
		} else {
			for ll = ncase.List; ll != nil; ll = ll.Next {
				setlineno(ll.N)
				typecheck(&ll.N, Erv|Etype)
				if ll.N.Type == nil || t == nil {
					continue
				}
				setlineno(ncase)
				switch top {
				// expression switch
				case Erv:
					defaultlit(&ll.N, t)
					switch {
					case ll.N.Op == OTYPE:
						Yyerror("type %v is not an expression", ll.N.Type)
					case ll.N.Type != nil && assignop(ll.N.Type, t, nil) == 0 && assignop(t, ll.N.Type, nil) == 0:
						if n.Left != nil {
							Yyerror("invalid case %v in switch on %v (mismatched types %v and %v)", ll.N, n.Left, ll.N.Type, t)
						} else {
							Yyerror("invalid case %v in switch (mismatched types %v and bool)", ll.N, ll.N.Type)
						}
					case nilonly != "" && !Isconst(ll.N, CTNIL):
						Yyerror("invalid case %v in switch (can only compare %s %v to nil)", ll.N, nilonly, n.Left)
					}

				// type switch
				case Etype:
					var missing, have *Type
					var ptr int
					switch {
					case ll.N.Op == OLITERAL && Istype(ll.N.Type, TNIL):
					case ll.N.Op != OTYPE && ll.N.Type != nil: // should this be ||?
						Yyerror("%v is not a type", Nconv(ll.N, obj.FmtLong))
						// reset to original type
						ll.N = n.Left.Right
					case ll.N.Type.Etype != TINTER && t.Etype == TINTER && !implements(ll.N.Type, t, &missing, &have, &ptr):
						if have != nil && !missing.Broke && !have.Broke {
							Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (wrong type for %v method)\n\thave %v%v\n\twant %v%v", Nconv(n.Left.Right, obj.FmtLong), ll.N.Type, missing.Sym, have.Sym, Tconv(have.Type, obj.FmtShort), missing.Sym, Tconv(missing.Type, obj.FmtShort))
						} else if !missing.Broke {
							Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (missing %v method)", Nconv(n.Left.Right, obj.FmtLong), ll.N.Type, missing.Sym)
						}
					}
				}
			}
		}

		if top == Etype && n.Type != nil {
			ll = ncase.List
			if ncase.Rlist != nil {
				nvar := ncase.Rlist.N
				if ll != nil && ll.Next == nil && ll.N.Type != nil && !Istype(ll.N.Type, TNIL) {
					// single entry type switch
					nvar.Name.Param.Ntype = typenod(ll.N.Type)
				} else {
					// multiple entry type switch or default
					nvar.Name.Param.Ntype = typenod(n.Type)
				}

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

		typechecklist(ncase.Nbody, Etop)
	}

	lineno = int32(lno)
}

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

	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) {
	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
		}
	}

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

	// convert the switch into OIF statements
	var cas *NodeList
	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 = list1(Nod(OAS, s.exprname, cond))
		typechecklist(cas, Etop)
	}

	// enumerate the cases, and lop off the default case
	cc := caseClauses(sw, s.kind)
	sw.List = nil
	var def *Node
	if len(cc) > 0 && cc[0].typ == caseKindDefault {
		def = cc[0].node.Right
		cc = cc[1:]
	} else {
		def = Nod(OBREAK, nil, nil)
	}

	// handle the cases in order
	for len(cc) > 0 {
		// deal with expressions one at a time
		if !okforcmp[t.Etype] || cc[0].typ != caseKindExprConst {
			a := s.walkCases(cc[:1])
			cas = list(cas, a)
			cc = cc[1:]
			continue
		}

		// do binary search on runs of constants
		var run int
		for run = 1; run < len(cc) && cc[run].typ == caseKindExprConst; run++ {
		}

		// sort and compile constants
		sort.Sort(caseClauseByExpr(cc[:run]))
		a := s.walkCases(cc[:run])
		cas = list(cas, a)
		cc = cc[run:]
	}

	// handle default case
	if nerrors == 0 {
		cas = list(cas, def)
		sw.Nbody = concat(cas, sw.Nbody)
		walkstmtlist(sw.Nbody)
	}
}

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

			a := Nod(OIF, nil, nil)
			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
				typecheck(&a.Left, Erv)
			} else if s.kind == switchKindTrue {
				a.Left = n.Left // if val
			} else {
				// s.kind == switchKindFalse
				a.Left = Nod(ONOT, n.Left, nil) // if !val
				typecheck(&a.Left, Erv)
			}
			a.Nbody = list1(n.Right) // goto l

			cas = list(cas, a)
			lineno = int32(lno)
		}
		return liststmt(cas)
	}

	// find the middle and recur
	half := len(cc) / 2
	a := Nod(OIF, nil, nil)
	mid := cc[half-1].node.Left
	le := Nod(OLE, s.exprname, mid)
	if Isconst(mid, CTSTR) {
		// Search by length and then by value; see exprcmp.
		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
	}
	typecheck(&a.Left, Erv)
	a.Nbody = list1(s.walkCases(cc[:half]))
	a.Rlist = list1(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 == nil {
		return
	}

	lno := setlineno(sw)

	var cas *NodeList  // cases
	var stat *NodeList // statements
	var def *Node      // defaults
	br := Nod(OBREAK, nil, nil)

	for l := sw.List; l != nil; l = l.Next {
		n := l.N
		setlineno(n)
		if n.Op != OXCASE {
			Fatalf("casebody %v", Oconv(int(n.Op), 0))
		}
		n.Op = OCASE
		needvar := count(n.List) != 1 || n.List.N.Op == OLITERAL

		jmp := Nod(OGOTO, newCaseLabel(), nil)
		if n.List == nil {
			if def != nil {
				Yyerror("more than one default case")
			}
			// reuse original default case
			n.Right = jmp
			def = n
		}

		if n.List != nil && n.List.Next == nil {
			// one case -- reuse OCASE node
			n.Left = n.List.N
			n.Right = jmp
			n.List = nil
			cas = list(cas, n)
		} else {
			// expand multi-valued cases
			for lc := n.List; lc != nil; lc = lc.Next {
				cas = list(cas, Nod(OCASE, lc.N, jmp))
			}
		}

		stat = list(stat, Nod(OLABEL, jmp.Left, nil))
		if typeswvar != nil && needvar && n.Rlist != nil {
			l := list1(Nod(ODCL, n.Rlist.N, nil))
			l = list(l, Nod(OAS, n.Rlist.N, typeswvar))
			typechecklist(l, Etop)
			stat = concat(stat, l)
		}
		stat = concat(stat, n.Nbody)

		// botch - shouldn't fall thru declaration
		last := stat.End.N
		if last.Xoffset == n.Xoffset && last.Op == OXFALL {
			if typeswvar != nil {
				setlineno(last)
				Yyerror("cannot fallthrough in type switch")
			}

			if l.Next == nil {
				setlineno(last)
				Yyerror("cannot fallthrough final case in switch")
			}

			last.Op = OFALL
		} else {
			stat = list(stat, br)
		}
	}

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

	sw.List = cas
	sw.Nbody = stat
	lineno = lno
}

// nSwitchLabel is the number of switch labels generated.
// This should be per-function, but it is a global counter for now.
var nSwitchLabel int

func newCaseLabel() *Node {
	label := strconv.Itoa(nSwitchLabel)
	nSwitchLabel++
	return newname(Lookup(label))
}

// caseClauses generates a slice of caseClauses
// corresponding to the clauses in the switch statement sw.
// Kind is the kind of switch statement.
func caseClauses(sw *Node, kind int) []*caseClause {
	var cc []*caseClause
	for l := sw.List; l != nil; l = l.Next {
		n := l.N
		c := new(caseClause)
		cc = append(cc, c)
		c.ordinal = len(cc)
		c.node = n

		if n.Left == nil {
			c.typ = caseKindDefault
			continue
		}

		if kind == switchKindType {
			// type switch
			switch {
			case n.Left.Op == OLITERAL:
				c.typ = caseKindTypeNil
			case Istype(n.Left.Type, TINTER):
				c.typ = caseKindTypeVar
			default:
				c.typ = caseKindTypeConst
				c.hash = typehash(n.Left.Type)
			}
		} else {
			// expression switch
			switch consttype(n.Left) {
			case CTFLT, CTINT, CTRUNE, CTSTR:
				c.typ = caseKindExprConst
			default:
				c.typ = caseKindExprVar
			}
		}
	}

	if cc == nil {
		return nil
	}

	// sort by value and diagnose duplicate cases
	if kind == switchKindType {
		// type switch
		sort.Sort(caseClauseByType(cc))
		for i, c1 := range cc {
			if c1.typ == caseKindTypeNil || c1.typ == caseKindDefault {
				break
			}
			for _, c2 := range cc[i+1:] {
				if c2.typ == caseKindTypeNil || c2.typ == caseKindDefault || c1.hash != c2.hash {
					break
				}
				if Eqtype(c1.node.Left.Type, c2.node.Left.Type) {
					yyerrorl(int(c2.node.Lineno), "duplicate case %v in type switch\n\tprevious case at %v", c2.node.Left.Type, c1.node.Line())
				}
			}
		}
	} else {
		// expression switch
		sort.Sort(caseClauseByExpr(cc))
		for i, c1 := range cc {
			if i+1 == len(cc) {
				break
			}
			c2 := cc[i+1]
			if exprcmp(c1, c2) != 0 {
				continue
			}
			setlineno(c2.node)
			Yyerror("duplicate case %v in switch\n\tprevious case at %v", c1.node.Left, c1.node.Line())
		}
	}

	// put list back in processing order
	sort.Sort(caseClauseByOrd(cc))
	return cc
}

// 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 = nil
		return
	}
	if cond.Right == nil {
		setlineno(sw)
		Yyerror("type switch must have an assignment")
		return
	}

	walkexpr(&cond.Right, &sw.Ninit)
	if !Istype(cond.Right.Type, TINTER) {
		Yyerror("type switch must be on an interface")
		return
	}

	var cas *NodeList

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

	a := Nod(OAS, s.facename, cond.Right)
	typecheck(&a, Etop)
	cas = list(cas, a)

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

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

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

	// calculate type hash
	t := cond.Right.Type
	if isnilinter(t) {
		a = syslook("efacethash", 1)
	} else {
		a = syslook("ifacethash", 1)
	}
	substArgTypes(a, t)
	a = Nod(OCALL, a, nil)
	a.List = list1(s.facename)
	a = Nod(OAS, s.hashname, a)
	typecheck(&a, Etop)
	cas = list(cas, a)

	cc := caseClauses(sw, switchKindType)
	sw.List = nil
	var def *Node
	if len(cc) > 0 && cc[0].typ == caseKindDefault {
		def = cc[0].node.Right
		cc = cc[1:]
	} else {
		def = Nod(OBREAK, nil, nil)
	}

	// insert type equality check into each case block
	for _, c := range cc {
		n := c.node
		switch c.typ {
		case caseKindTypeNil:
			var v Val
			v.U = new(NilVal)
			a = Nod(OIF, nil, nil)
			a.Left = Nod(OEQ, s.facename, nodlit(v))
			typecheck(&a.Left, Erv)
			a.Nbody = list1(n.Right) // if i==nil { goto l }
			n.Right = a

		case caseKindTypeVar, caseKindTypeConst:
			n.Right = s.typeone(n)
		}
	}

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

		// identify run of constants
		var run int
		for run = 1; run < len(cc) && cc[run].typ == caseKindTypeConst; 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 = list(cas, n.Right)
			}
			continue
		}

		// combine adjacent cases with the same hash
		ncase := 0
		for i := 0; i < run; i++ {
			ncase++
			hash := list1(cc[i].node.Right)
			for j := i + 1; j < run && cc[i].hash == cc[j].hash; j++ {
				hash = list(hash, cc[j].node.Right)
			}
			cc[i].node.Right = liststmt(hash)
		}

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

	// handle default case
	if nerrors == 0 {
		cas = list(cas, def)
		sw.Nbody = concat(cas, sw.Nbody)
		sw.List = nil
		walkstmtlist(sw.Nbody)
	}
}

// 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 *NodeList
	if t.Rlist == nil {
		name = nblank
		typecheck(&nblank, Erv|Easgn)
	} else {
		name = t.Rlist.N
		init = list1(Nod(ODCL, name, nil))
		a := Nod(OAS, name, nil)
		typecheck(&a, Etop)
		init = list(init, a)
	}

	a := Nod(OAS2, nil, nil)
	a.List = list(list1(name), s.okname) // name, ok =
	b := Nod(ODOTTYPE, s.facename, nil)
	b.Type = t.Left.Type // interface.(type)
	a.Rlist = list1(b)
	typecheck(&a, Etop)
	init = list(init, a)

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

	return liststmt(list(init, c))
}

// walkCases generates an AST implementing the cases in cc.
func (s *typeSwitch) walkCases(cc []*caseClause) *Node {
	if len(cc) < binarySearchMin {
		var cas *NodeList
		for _, c := range cc {
			n := c.node
			if c.typ != caseKindTypeConst {
				Fatalf("typeSwitch walkCases")
			}
			a := Nod(OIF, nil, nil)
			a.Left = Nod(OEQ, s.hashname, Nodintconst(int64(c.hash)))
			typecheck(&a.Left, Erv)
			a.Nbody = list1(n.Right)
			cas = list(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)))
	typecheck(&a.Left, Erv)
	a.Nbody = list1(s.walkCases(cc[:half]))
	a.Rlist = list1(s.walkCases(cc[half:]))
	return a
}

type caseClauseByOrd []*caseClause

func (x caseClauseByOrd) Len() int      { return len(x) }
func (x caseClauseByOrd) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x caseClauseByOrd) Less(i, j int) bool {
	c1, c2 := x[i], x[j]
	switch {
	// sort default first
	case c1.typ == caseKindDefault:
		return true
	case c2.typ == caseKindDefault:
		return false

	// sort nil second
	case c1.typ == caseKindTypeNil:
		return true
	case c2.typ == caseKindTypeNil:
		return false
	}

	// sort by ordinal
	return c1.ordinal < c2.ordinal
}

type caseClauseByExpr []*caseClause

func (x caseClauseByExpr) Len() int      { return len(x) }
func (x caseClauseByExpr) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x caseClauseByExpr) Less(i, j int) bool {
	return exprcmp(x[i], x[j]) < 0
}

func exprcmp(c1, c2 *caseClause) int {
	// sort non-constants last
	if c1.typ != caseKindExprConst {
		return +1
	}
	if c2.typ != caseKindExprConst {
		return -1
	}

	n1 := c1.node.Left
	n2 := c2.node.Left

	// sort by type (for switches on interface)
	ct := int(n1.Val().Ctype())
	if ct > int(n2.Val().Ctype()) {
		return +1
	}
	if ct < int(n2.Val().Ctype()) {
		return -1
	}
	if !Eqtype(n1.Type, n2.Type) {
		if n1.Type.Vargen > n2.Type.Vargen {
			return +1
		} else {
			return -1
		}
	}

	// sort by constant value to enable binary search
	switch ct {
	case CTFLT:
		return mpcmpfltflt(n1.Val().U.(*Mpflt), n2.Val().U.(*Mpflt))
	case CTINT, CTRUNE:
		return Mpcmpfixfix(n1.Val().U.(*Mpint), n2.Val().U.(*Mpint))
	case CTSTR:
		// 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 := n1.Val().U.(string)
		b := n2.Val().U.(string)
		if len(a) < len(b) {
			return -1
		}
		if len(a) > len(b) {
			return +1
		}
		return stringsCompare(a, b)
	}

	return 0
}

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]
	switch {
	// sort non-constants last
	case c1.typ != caseKindTypeConst:
		return false
	case c2.typ != caseKindTypeConst:
		return true

	// sort by hash code
	case c1.hash != c2.hash:
		return c1.hash < c2.hash
	}

	// sort by ordinal
	return c1.ordinal < c2.ordinal
}

func dumpcase(cc []*caseClause) {
	for _, c := range cc {
		switch c.typ {
		case caseKindDefault:
			fmt.Printf("case-default\n")
			fmt.Printf("\tord=%d\n", c.ordinal)

		case caseKindExprConst:
			fmt.Printf("case-exprconst\n")
			fmt.Printf("\tord=%d\n", c.ordinal)

		case caseKindExprVar:
			fmt.Printf("case-exprvar\n")
			fmt.Printf("\tord=%d\n", c.ordinal)
			fmt.Printf("\top=%v\n", Oconv(int(c.node.Left.Op), 0))

		case caseKindTypeNil:
			fmt.Printf("case-typenil\n")
			fmt.Printf("\tord=%d\n", c.ordinal)

		case caseKindTypeConst:
			fmt.Printf("case-typeconst\n")
			fmt.Printf("\tord=%d\n", c.ordinal)
			fmt.Printf("\thash=%x\n", c.hash)

		case caseKindTypeVar:
			fmt.Printf("case-typevar\n")
			fmt.Printf("\tord=%d\n", c.ordinal)

		default:
			fmt.Printf("case-???\n")
			fmt.Printf("\tord=%d\n", c.ordinal)
			fmt.Printf("\top=%v\n", Oconv(int(c.node.Left.Op), 0))
			fmt.Printf("\thash=%x\n", c.hash)
		}
	}

	fmt.Printf("\n")
}
