Commit 65c4b55a authored by Ian Lance Taylor's avatar Ian Lance Taylor

cmd/compile: convert subr, swt, typecheck to nodeSeq

Passes toolstash -cmp.

Update #14473.

Change-Id: I836197810405cde72cbb49fef7e163a517601f9c
Reviewed-on: https://go-review.googlesource.com/20242Reviewed-by: default avatarDavid Crawshaw <crawshaw@golang.org>
parent 3da1a26f
...@@ -297,19 +297,19 @@ func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList { ...@@ -297,19 +297,19 @@ func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList {
lastconst = cl lastconst = cl
lasttype = t lasttype = t
} }
cl = listtreecopy(cl, lno) clcopy := listtreecopy(cl, lno)
var v *Node var v *Node
var c *Node var c *Node
var vv *NodeList var vv *NodeList
for ; vl != nil; vl = vl.Next { for ; vl != nil; vl = vl.Next {
if cl == nil { if len(clcopy) == 0 {
Yyerror("missing value in const declaration") Yyerror("missing value in const declaration")
break break
} }
c = cl.N c = clcopy[0]
cl = cl.Next clcopy = clcopy[1:]
v = vl.N v = vl.N
v.Op = OLITERAL v.Op = OLITERAL
...@@ -321,7 +321,7 @@ func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList { ...@@ -321,7 +321,7 @@ func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList {
vv = list(vv, Nod(ODCLCONST, v, nil)) vv = list(vv, Nod(ODCLCONST, v, nil))
} }
if cl != nil { if len(clcopy) != 0 {
Yyerror("extra expression in const declaration") Yyerror("extra expression in const declaration")
} }
iota_ += 1 iota_ += 1
......
...@@ -536,7 +536,7 @@ func treecopy(n *Node, lineno int32) *Node { ...@@ -536,7 +536,7 @@ func treecopy(n *Node, lineno int32) *Node {
m.Orig = m m.Orig = m
m.Left = treecopy(n.Left, lineno) m.Left = treecopy(n.Left, lineno)
m.Right = treecopy(n.Right, lineno) m.Right = treecopy(n.Right, lineno)
m.List = listtreecopy(n.List, lineno) setNodeSeq(&m.List, listtreecopy(n.List, lineno))
if lineno != 0 { if lineno != 0 {
m.Lineno = lineno m.Lineno = lineno
} }
...@@ -1393,7 +1393,7 @@ func ullmancalc(n *Node) { ...@@ -1393,7 +1393,7 @@ func ullmancalc(n *Node) {
var ul int var ul int
var ur int var ur int
if n.Ninit != nil { if nodeSeqLen(n.Ninit) != 0 {
ul = UINF ul = UINF
goto out goto out
} }
...@@ -2014,13 +2014,13 @@ func expandmeth(t *Type) { ...@@ -2014,13 +2014,13 @@ func expandmeth(t *Type) {
} }
// Given funarg struct list, return list of ODCLFIELD Node fn args. // Given funarg struct list, return list of ODCLFIELD Node fn args.
func structargs(tl **Type, mustname int) *NodeList { func structargs(tl **Type, mustname int) []*Node {
var savet Iter var savet Iter
var a *Node var a *Node
var n *Node var n *Node
var buf string var buf string
var args *NodeList var args []*Node
gen := 0 gen := 0
for t := Structfirst(&savet, tl); t != nil; t = structnext(&savet) { for t := Structfirst(&savet, tl); t != nil; t = structnext(&savet) {
n = nil n = nil
...@@ -2038,7 +2038,7 @@ func structargs(tl **Type, mustname int) *NodeList { ...@@ -2038,7 +2038,7 @@ func structargs(tl **Type, mustname int) *NodeList {
if n != nil { if n != nil {
n.Isddd = t.Isddd n.Isddd = t.Isddd
} }
args = list(args, a) args = append(args, a)
} }
return args return args
...@@ -2091,7 +2091,7 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { ...@@ -2091,7 +2091,7 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) {
out := structargs(Getoutarg(method.Type), 0) out := structargs(Getoutarg(method.Type), 0)
t := Nod(OTFUNC, nil, nil) t := Nod(OTFUNC, nil, nil)
l := list1(this) l := []*Node{this}
if iface != 0 && rcvr.Width < Types[Tptr].Width { if iface != 0 && rcvr.Width < Types[Tptr].Width {
// Building method for interface table and receiver // Building method for interface table and receiver
// is smaller than the single pointer-sized word // is smaller than the single pointer-sized word
...@@ -2103,11 +2103,11 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { ...@@ -2103,11 +2103,11 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) {
tpad.Type = Types[TUINT8] tpad.Type = Types[TUINT8]
tpad.Bound = Types[Tptr].Width - rcvr.Width tpad.Bound = Types[Tptr].Width - rcvr.Width
pad := Nod(ODCLFIELD, newname(Lookup(".pad")), typenod(tpad)) pad := Nod(ODCLFIELD, newname(Lookup(".pad")), typenod(tpad))
l = list(l, pad) l = append(l, pad)
} }
t.List = concat(l, in) setNodeSeq(&t.List, append(l, in...))
t.Rlist = out setNodeSeq(&t.Rlist, out)
fn := Nod(ODCLFUNC, nil, nil) fn := Nod(ODCLFUNC, nil, nil)
fn.Func.Nname = newname(newnam) fn.Func.Nname = newname(newnam)
...@@ -2117,12 +2117,12 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { ...@@ -2117,12 +2117,12 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) {
funchdr(fn) funchdr(fn)
// arg list // arg list
var args *NodeList var args []*Node
isddd := false isddd := false
for l := in; l != nil; l = l.Next { for _, n := range in {
args = list(args, l.N.Left) args = append(args, n.Left)
isddd = l.N.Left.Isddd isddd = n.Left.Isddd
} }
methodrcvr := getthisx(method.Type).Type.Type methodrcvr := getthisx(method.Type).Type.Type
...@@ -2136,17 +2136,17 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { ...@@ -2136,17 +2136,17 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) {
// these strings are already in the reflect tables, // these strings are already in the reflect tables,
// so no space cost to use them here. // so no space cost to use them here.
var l *NodeList var l []*Node
var v Val var v Val
v.U = rcvr.Type.Sym.Pkg.Name // package name v.U = rcvr.Type.Sym.Pkg.Name // package name
l = list(l, nodlit(v)) l = append(l, nodlit(v))
v.U = rcvr.Type.Sym.Name // type name v.U = rcvr.Type.Sym.Name // type name
l = list(l, nodlit(v)) l = append(l, nodlit(v))
v.U = method.Sym.Name v.U = method.Sym.Name
l = list(l, nodlit(v)) // method name l = append(l, nodlit(v)) // method name
call := Nod(OCALL, syslook("panicwrap"), nil) call := Nod(OCALL, syslook("panicwrap"), nil)
call.List = l setNodeSeq(&call.List, l)
n.Nbody.Set([]*Node{call}) n.Nbody.Set([]*Node{call})
fn.Nbody.Append(n) fn.Nbody.Append(n)
} }
...@@ -2169,11 +2169,11 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { ...@@ -2169,11 +2169,11 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) {
} else { } else {
fn.Func.Wrapper = true // ignore frame for panic+recover matching fn.Func.Wrapper = true // ignore frame for panic+recover matching
call := Nod(OCALL, dot, nil) call := Nod(OCALL, dot, nil)
call.List = args setNodeSeq(&call.List, args)
call.Isddd = isddd call.Isddd = isddd
if method.Type.Outtuple > 0 { if method.Type.Outtuple > 0 {
n := Nod(ORETURN, nil, nil) n := Nod(ORETURN, nil, nil)
n.List = list1(call) setNodeSeq(&n.List, []*Node{call})
call = n call = n
} }
...@@ -2207,10 +2207,10 @@ func hashmem(t *Type) *Node { ...@@ -2207,10 +2207,10 @@ func hashmem(t *Type) *Node {
n := newname(sym) n := newname(sym)
n.Class = PFUNC n.Class = PFUNC
tfn := Nod(OTFUNC, nil, nil) tfn := Nod(OTFUNC, nil, nil)
tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t)))) appendNodeSeqNode(&tfn.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) appendNodeSeqNode(&tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) appendNodeSeqNode(&tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
tfn.Rlist = list(tfn.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) appendNodeSeqNode(&tfn.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
typecheck(&tfn, Etype) typecheck(&tfn, Etype)
n.Type = tfn.Type n.Type = tfn.Type
return n return n
...@@ -2354,10 +2354,10 @@ func Simsimtype(t *Type) EType { ...@@ -2354,10 +2354,10 @@ func Simsimtype(t *Type) EType {
return et return et
} }
func listtreecopy(l *NodeList, lineno int32) *NodeList { func listtreecopy(l nodesOrNodeList, lineno int32) []*Node {
var out *NodeList var out []*Node
for ; l != nil; l = l.Next { for it := nodeSeqIterate(l); !it.Done(); it.Next() {
out = list(out, treecopy(l.N, lineno)) out = append(out, treecopy(it.N(), lineno))
} }
return out return out
} }
......
...@@ -105,11 +105,10 @@ func typecheckswitch(n *Node) { ...@@ -105,11 +105,10 @@ func typecheckswitch(n *Node) {
n.Type = t n.Type = t
var def *Node var def *Node
var ll *NodeList for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
for l := n.List; l != nil; l = l.Next { ncase := it.N()
ncase := l.N
setlineno(n) setlineno(n)
if ncase.List == nil { if nodeSeqLen(ncase.List) == 0 {
// default // default
if def != nil { if def != nil {
Yyerror("multiple defaults in switch (first at %v)", def.Line()) Yyerror("multiple defaults in switch (first at %v)", def.Line())
...@@ -117,30 +116,30 @@ func typecheckswitch(n *Node) { ...@@ -117,30 +116,30 @@ func typecheckswitch(n *Node) {
def = ncase def = ncase
} }
} else { } else {
for ll = ncase.List; ll != nil; ll = ll.Next { for it2 := nodeSeqIterate(ncase.List); !it2.Done(); it2.Next() {
setlineno(ll.N) setlineno(it2.N())
typecheck(&ll.N, Erv|Etype) typecheck(it2.P(), Erv|Etype)
if ll.N.Type == nil || t == nil { if it2.N().Type == nil || t == nil {
continue continue
} }
setlineno(ncase) setlineno(ncase)
switch top { switch top {
// expression switch // expression switch
case Erv: case Erv:
defaultlit(&ll.N, t) defaultlit(it2.P(), t)
switch { switch {
case ll.N.Op == OTYPE: case it2.N().Op == OTYPE:
Yyerror("type %v is not an expression", ll.N.Type) Yyerror("type %v is not an expression", it2.N().Type)
case ll.N.Type != nil && assignop(ll.N.Type, t, nil) == 0 && assignop(t, ll.N.Type, nil) == 0: case it2.N().Type != nil && assignop(it2.N().Type, t, nil) == 0 && assignop(t, it2.N().Type, nil) == 0:
if n.Left != nil { 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) Yyerror("invalid case %v in switch on %v (mismatched types %v and %v)", it2.N(), n.Left, it2.N().Type, t)
} else { } else {
Yyerror("invalid case %v in switch (mismatched types %v and bool)", ll.N, ll.N.Type) Yyerror("invalid case %v in switch (mismatched types %v and bool)", it2.N(), it2.N().Type)
} }
case nilonly != "" && !isnil(ll.N): case nilonly != "" && !isnil(it2.N()):
Yyerror("invalid case %v in switch (can only compare %s %v to nil)", ll.N, nilonly, n.Left) Yyerror("invalid case %v in switch (can only compare %s %v to nil)", it2.N(), nilonly, n.Left)
case Isinter(t) && !Isinter(ll.N.Type) && algtype1(ll.N.Type, nil) == ANOEQ: case Isinter(t) && !Isinter(it2.N().Type) && algtype1(it2.N().Type, nil) == ANOEQ:
Yyerror("invalid case %v in switch (incomparable type)", Nconv(ll.N, obj.FmtLong)) Yyerror("invalid case %v in switch (incomparable type)", Nconv(it2.N(), obj.FmtLong))
} }
// type switch // type switch
...@@ -148,16 +147,16 @@ func typecheckswitch(n *Node) { ...@@ -148,16 +147,16 @@ func typecheckswitch(n *Node) {
var missing, have *Type var missing, have *Type
var ptr int var ptr int
switch { switch {
case ll.N.Op == OLITERAL && Istype(ll.N.Type, TNIL): case it2.N().Op == OLITERAL && Istype(it2.N().Type, TNIL):
case ll.N.Op != OTYPE && ll.N.Type != nil: // should this be ||? case it2.N().Op != OTYPE && it2.N().Type != nil: // should this be ||?
Yyerror("%v is not a type", Nconv(ll.N, obj.FmtLong)) Yyerror("%v is not a type", Nconv(it2.N(), obj.FmtLong))
// reset to original type // reset to original type
ll.N = n.Left.Right *it2.P() = n.Left.Right
case ll.N.Type.Etype != TINTER && t.Etype == TINTER && !implements(ll.N.Type, t, &missing, &have, &ptr): case it2.N().Type.Etype != TINTER && t.Etype == TINTER && !implements(it2.N().Type, t, &missing, &have, &ptr):
if have != nil && !missing.Broke && !have.Broke { 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)) 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), it2.N().Type, missing.Sym, have.Sym, Tconv(have.Type, obj.FmtShort), missing.Sym, Tconv(missing.Type, obj.FmtShort))
} else if !missing.Broke { } 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) Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (missing %v method)", Nconv(n.Left.Right, obj.FmtLong), it2.N().Type, missing.Sym)
} }
} }
} }
...@@ -165,19 +164,20 @@ func typecheckswitch(n *Node) { ...@@ -165,19 +164,20 @@ func typecheckswitch(n *Node) {
} }
if top == Etype && n.Type != nil { if top == Etype && n.Type != nil {
ll = ncase.List ll := ncase.List
if ncase.Rlist != nil { if nodeSeqLen(ncase.Rlist) != 0 {
nvar := ncase.Rlist.N nvar := nodeSeqFirst(ncase.Rlist)
if ll != nil && ll.Next == nil && ll.N.Type != nil && !Istype(ll.N.Type, TNIL) { if nodeSeqLen(ll) == 1 && nodeSeqFirst(ll).Type != nil && !Istype(nodeSeqFirst(ll).Type, TNIL) {
// single entry type switch // single entry type switch
nvar.Name.Param.Ntype = typenod(ll.N.Type) nvar.Name.Param.Ntype = typenod(nodeSeqFirst(ll).Type)
} else { } else {
// multiple entry type switch or default // multiple entry type switch or default
nvar.Name.Param.Ntype = typenod(n.Type) nvar.Name.Param.Ntype = typenod(n.Type)
} }
typecheck(&nvar, Erv|Easgn) typecheck(&nvar, Erv|Easgn)
ncase.Rlist.N = nvar rit := nodeSeqIterate(ncase.Rlist)
*rit.P() = nvar
} }
} }
...@@ -244,7 +244,7 @@ func (s *exprSwitch) walk(sw *Node) { ...@@ -244,7 +244,7 @@ func (s *exprSwitch) walk(sw *Node) {
// enumerate the cases, and lop off the default case // enumerate the cases, and lop off the default case
cc := caseClauses(sw, s.kind) cc := caseClauses(sw, s.kind)
sw.List = nil setNodeSeq(&sw.List, nil)
var def *Node var def *Node
if len(cc) > 0 && cc[0].typ == caseKindDefault { if len(cc) > 0 && cc[0].typ == caseKindDefault {
def = cc[0].node.Right def = cc[0].node.Right
...@@ -326,7 +326,7 @@ func (s *exprSwitch) walkCases(cc []*caseClause) *Node { ...@@ -326,7 +326,7 @@ func (s *exprSwitch) walkCases(cc []*caseClause) *Node {
} }
typecheck(&a.Left, Erv) typecheck(&a.Left, Erv)
a.Nbody.Set([]*Node{s.walkCases(cc[:half])}) a.Nbody.Set([]*Node{s.walkCases(cc[:half])})
a.Rlist = list1(s.walkCases(cc[half:])) setNodeSeq(&a.Rlist, []*Node{s.walkCases(cc[half:])})
return a return a
} }
...@@ -334,28 +334,28 @@ func (s *exprSwitch) walkCases(cc []*caseClause) *Node { ...@@ -334,28 +334,28 @@ func (s *exprSwitch) walkCases(cc []*caseClause) *Node {
// It makes labels between cases and statements // It makes labels between cases and statements
// and deals with fallthrough, break, and unreachable statements. // and deals with fallthrough, break, and unreachable statements.
func casebody(sw *Node, typeswvar *Node) { func casebody(sw *Node, typeswvar *Node) {
if sw.List == nil { if nodeSeqLen(sw.List) == 0 {
return return
} }
lno := setlineno(sw) lno := setlineno(sw)
var cas *NodeList // cases var cas []*Node // cases
var stat []*Node // statements var stat []*Node // statements
var def *Node // defaults var def *Node // defaults
br := Nod(OBREAK, nil, nil) br := Nod(OBREAK, nil, nil)
for l := sw.List; l != nil; l = l.Next { for it := nodeSeqIterate(sw.List); !it.Done(); it.Next() {
n := l.N n := it.N()
setlineno(n) setlineno(n)
if n.Op != OXCASE { if n.Op != OXCASE {
Fatalf("casebody %v", Oconv(int(n.Op), 0)) Fatalf("casebody %v", Oconv(int(n.Op), 0))
} }
n.Op = OCASE n.Op = OCASE
needvar := count(n.List) != 1 || n.List.N.Op == OLITERAL needvar := nodeSeqLen(n.List) != 1 || nodeSeqFirst(n.List).Op == OLITERAL
jmp := Nod(OGOTO, newCaseLabel(), nil) jmp := Nod(OGOTO, newCaseLabel(), nil)
if n.List == nil { if nodeSeqLen(n.List) == 0 {
if def != nil { if def != nil {
Yyerror("more than one default case") Yyerror("more than one default case")
} }
...@@ -364,24 +364,24 @@ func casebody(sw *Node, typeswvar *Node) { ...@@ -364,24 +364,24 @@ func casebody(sw *Node, typeswvar *Node) {
def = n def = n
} }
if n.List != nil && n.List.Next == nil { if nodeSeqLen(n.List) == 1 {
// one case -- reuse OCASE node // one case -- reuse OCASE node
n.Left = n.List.N n.Left = nodeSeqFirst(n.List)
n.Right = jmp n.Right = jmp
n.List = nil setNodeSeq(&n.List, nil)
cas = list(cas, n) cas = append(cas, n)
} else { } else {
// expand multi-valued cases // expand multi-valued cases
for lc := n.List; lc != nil; lc = lc.Next { for lcit := nodeSeqIterate(n.List); !lcit.Done(); lcit.Next() {
cas = list(cas, Nod(OCASE, lc.N, jmp)) cas = append(cas, Nod(OCASE, lcit.N(), jmp))
} }
} }
stat = append(stat, Nod(OLABEL, jmp.Left, nil)) stat = append(stat, Nod(OLABEL, jmp.Left, nil))
if typeswvar != nil && needvar && n.Rlist != nil { if typeswvar != nil && needvar && nodeSeqLen(n.Rlist) != 0 {
l := []*Node{ l := []*Node{
Nod(ODCL, n.Rlist.N, nil), Nod(ODCL, nodeSeqFirst(n.Rlist), nil),
Nod(OAS, n.Rlist.N, typeswvar), Nod(OAS, nodeSeqFirst(n.Rlist), typeswvar),
} }
typecheckslice(l, Etop) typecheckslice(l, Etop)
stat = append(stat, l...) stat = append(stat, l...)
...@@ -396,7 +396,7 @@ func casebody(sw *Node, typeswvar *Node) { ...@@ -396,7 +396,7 @@ func casebody(sw *Node, typeswvar *Node) {
Yyerror("cannot fallthrough in type switch") Yyerror("cannot fallthrough in type switch")
} }
if l.Next == nil { if it.Len() <= 1 {
setlineno(last) setlineno(last)
Yyerror("cannot fallthrough final case in switch") Yyerror("cannot fallthrough final case in switch")
} }
...@@ -409,10 +409,10 @@ func casebody(sw *Node, typeswvar *Node) { ...@@ -409,10 +409,10 @@ func casebody(sw *Node, typeswvar *Node) {
stat = append(stat, br) stat = append(stat, br)
if def != nil { if def != nil {
cas = list(cas, def) cas = append(cas, def)
} }
sw.List = cas setNodeSeq(&sw.List, cas)
sw.Nbody.Set(stat) sw.Nbody.Set(stat)
lineno = lno lineno = lno
} }
...@@ -432,8 +432,8 @@ func newCaseLabel() *Node { ...@@ -432,8 +432,8 @@ func newCaseLabel() *Node {
// Kind is the kind of switch statement. // Kind is the kind of switch statement.
func caseClauses(sw *Node, kind int) []*caseClause { func caseClauses(sw *Node, kind int) []*caseClause {
var cc []*caseClause var cc []*caseClause
for l := sw.List; l != nil; l = l.Next { for it := nodeSeqIterate(sw.List); !it.Done(); it.Next() {
n := l.N n := it.N()
c := new(caseClause) c := new(caseClause)
cc = append(cc, c) cc = append(cc, c)
c.ordinal = len(cc) c.ordinal = len(cc)
...@@ -518,7 +518,7 @@ func (s *typeSwitch) walk(sw *Node) { ...@@ -518,7 +518,7 @@ func (s *typeSwitch) walk(sw *Node) {
sw.Left = nil sw.Left = nil
if cond == nil { if cond == nil {
sw.List = nil setNodeSeq(&sw.List, nil)
return return
} }
if cond.Right == nil { if cond.Right == nil {
...@@ -552,7 +552,7 @@ func (s *typeSwitch) walk(sw *Node) { ...@@ -552,7 +552,7 @@ func (s *typeSwitch) walk(sw *Node) {
casebody(sw, s.facename) casebody(sw, s.facename)
cc := caseClauses(sw, switchKindType) cc := caseClauses(sw, switchKindType)
sw.List = nil setNodeSeq(&sw.List, nil)
var def *Node var def *Node
if len(cc) > 0 && cc[0].typ == caseKindDefault { if len(cc) > 0 && cc[0].typ == caseKindDefault {
def = cc[0].node.Right def = cc[0].node.Right
...@@ -588,7 +588,7 @@ func (s *typeSwitch) walk(sw *Node) { ...@@ -588,7 +588,7 @@ func (s *typeSwitch) walk(sw *Node) {
i.Nbody.Set([]*Node{Nod(OGOTO, lbl, nil)}) i.Nbody.Set([]*Node{Nod(OGOTO, lbl, nil)})
// Wrap default case with label. // Wrap default case with label.
blk := Nod(OBLOCK, nil, nil) blk := Nod(OBLOCK, nil, nil)
blk.List = list(list1(Nod(OLABEL, lbl, nil)), def) setNodeSeq(&blk.List, []*Node{Nod(OLABEL, lbl, nil), def})
def = blk def = blk
} }
typecheck(&i.Left, Erv) typecheck(&i.Left, Erv)
...@@ -669,7 +669,7 @@ func (s *typeSwitch) walk(sw *Node) { ...@@ -669,7 +669,7 @@ func (s *typeSwitch) walk(sw *Node) {
if nerrors == 0 { if nerrors == 0 {
cas = append(cas, def) cas = append(cas, def)
sw.Nbody.Set(append(cas, sw.Nbody.Slice()...)) sw.Nbody.Set(append(cas, sw.Nbody.Slice()...))
sw.List = nil setNodeSeq(&sw.List, nil)
walkstmtlist(sw.Nbody) walkstmtlist(sw.Nbody)
} }
} }
...@@ -679,11 +679,11 @@ func (s *typeSwitch) walk(sw *Node) { ...@@ -679,11 +679,11 @@ func (s *typeSwitch) walk(sw *Node) {
func (s *typeSwitch) typeone(t *Node) *Node { func (s *typeSwitch) typeone(t *Node) *Node {
var name *Node var name *Node
var init *NodeList var init *NodeList
if t.Rlist == nil { if nodeSeqLen(t.Rlist) == 0 {
name = nblank name = nblank
typecheck(&nblank, Erv|Easgn) typecheck(&nblank, Erv|Easgn)
} else { } else {
name = t.Rlist.N name = nodeSeqFirst(t.Rlist)
init = list1(Nod(ODCL, name, nil)) init = list1(Nod(ODCL, name, nil))
a := Nod(OAS, name, nil) a := Nod(OAS, name, nil)
typecheck(&a, Etop) typecheck(&a, Etop)
...@@ -691,10 +691,10 @@ func (s *typeSwitch) typeone(t *Node) *Node { ...@@ -691,10 +691,10 @@ func (s *typeSwitch) typeone(t *Node) *Node {
} }
a := Nod(OAS2, nil, nil) a := Nod(OAS2, nil, nil)
a.List = list(list1(name), s.okname) // name, ok = setNodeSeq(&a.List, []*Node{name, s.okname}) // name, ok =
b := Nod(ODOTTYPE, s.facename, nil) b := Nod(ODOTTYPE, s.facename, nil)
b.Type = t.Left.Type // interface.(type) b.Type = t.Left.Type // interface.(type)
a.Rlist = list1(b) setNodeSeq(&a.Rlist, []*Node{b})
typecheck(&a, Etop) typecheck(&a, Etop)
init = list(init, a) init = list(init, a)
...@@ -729,7 +729,7 @@ func (s *typeSwitch) walkCases(cc []*caseClause) *Node { ...@@ -729,7 +729,7 @@ func (s *typeSwitch) walkCases(cc []*caseClause) *Node {
a.Left = Nod(OLE, s.hashname, Nodintconst(int64(cc[half-1].hash))) a.Left = Nod(OLE, s.hashname, Nodintconst(int64(cc[half-1].hash)))
typecheck(&a.Left, Erv) typecheck(&a.Left, Erv)
a.Nbody.Set([]*Node{s.walkCases(cc[:half])}) a.Nbody.Set([]*Node{s.walkCases(cc[:half])})
a.Rlist = list1(s.walkCases(cc[half:])) setNodeSeq(&a.Rlist, []*Node{s.walkCases(cc[half:])})
return a return a
} }
......
...@@ -391,12 +391,12 @@ func list1(n *Node) *NodeList { ...@@ -391,12 +391,12 @@ func list1(n *Node) *NodeList {
if n == nil { if n == nil {
return nil return nil
} }
if n.Op == OBLOCK && n.Ninit == nil { if n.Op == OBLOCK && nodeSeqLen(n.Ninit) == 0 {
// Flatten list and steal storage. // Flatten list and steal storage.
// Poison pointer to catch errant uses. // Poison pointer to catch errant uses.
l := n.List l := n.List
n.List = nil setNodeSeq(&n.List, nil)
return l return l
} }
......
...@@ -217,21 +217,12 @@ func callrecv(n *Node) bool { ...@@ -217,21 +217,12 @@ func callrecv(n *Node) bool {
return true return true
} }
return callrecv(n.Left) || callrecv(n.Right) || callrecvlist(n.Ninit) || callrecvslice(n.Nbody.Slice()) || callrecvlist(n.List) || callrecvlist(n.Rlist) return callrecv(n.Left) || callrecv(n.Right) || callrecvlist(n.Ninit) || callrecvlist(n.Nbody) || callrecvlist(n.List) || callrecvlist(n.Rlist)
} }
func callrecvlist(l *NodeList) bool { func callrecvlist(l nodesOrNodeList) bool {
for ; l != nil; l = l.Next { for it := nodeSeqIterate(l); !it.Done(); it.Next() {
if callrecv(l.N) { if callrecv(it.N()) {
return true
}
}
return false
}
func callrecvslice(l []*Node) bool {
for _, n := range l {
if callrecv(n) {
return true return true
} }
} }
...@@ -440,7 +431,7 @@ OpSwitch: ...@@ -440,7 +431,7 @@ OpSwitch:
n.Type = nil n.Type = nil
return return
} }
n.List = nil setNodeSeq(&n.List, nil)
case OTINTER: case OTINTER:
ok |= Etype ok |= Etype
...@@ -714,14 +705,14 @@ OpSwitch: ...@@ -714,14 +705,14 @@ OpSwitch:
n.Op = OADDSTR n.Op = OADDSTR
if l.Op == OADDSTR { if l.Op == OADDSTR {
n.List = l.List setNodeSeq(&n.List, l.List)
} else { } else {
n.List = list1(l) setNodeSeq(&n.List, []*Node{l})
} }
if r.Op == OADDSTR { if r.Op == OADDSTR {
n.List = concat(n.List, r.List) appendNodeSeq(&n.List, r.List)
} else { } else {
n.List = list(n.List, r) appendNodeSeqNode(&n.List, r)
} }
n.Left = nil n.Left = nil
n.Right = nil n.Right = nil
...@@ -1298,8 +1289,9 @@ OpSwitch: ...@@ -1298,8 +1289,9 @@ OpSwitch:
return return
} }
if count(n.List) == 1 && !n.Isddd { if nodeSeqLen(n.List) == 1 && !n.Isddd {
typecheck(&n.List.N, Erv|Efnstruct) it := nodeSeqIterate(n.List)
typecheck(it.P(), Erv|Efnstruct)
} else { } else {
typechecklist(n.List, Erv) typechecklist(n.List, Erv)
} }
...@@ -1455,22 +1447,22 @@ OpSwitch: ...@@ -1455,22 +1447,22 @@ OpSwitch:
ok |= Erv ok |= Erv
var r *Node var r *Node
var l *Node var l *Node
if count(n.List) == 1 { if nodeSeqLen(n.List) == 1 {
typechecklist(n.List, Efnstruct) typechecklist(n.List, Efnstruct)
if n.List.N.Op != OCALLFUNC && n.List.N.Op != OCALLMETH { if nodeSeqFirst(n.List).Op != OCALLFUNC && nodeSeqFirst(n.List).Op != OCALLMETH {
Yyerror("invalid operation: complex expects two arguments") Yyerror("invalid operation: complex expects two arguments")
n.Type = nil n.Type = nil
return return
} }
t := n.List.N.Left.Type t := nodeSeqFirst(n.List).Left.Type
if t.Outtuple != 2 { if t.Outtuple != 2 {
Yyerror("invalid operation: complex expects two arguments, %v returns %d results", n.List.N, t.Outtuple) Yyerror("invalid operation: complex expects two arguments, %v returns %d results", nodeSeqFirst(n.List), t.Outtuple)
n.Type = nil n.Type = nil
return return
} }
t = n.List.N.Type.Type t = nodeSeqFirst(n.List).Type.Type
l = t.Nname l = t.Nname
r = t.Down.Nname r = t.Down.Nname
} else { } else {
...@@ -1557,19 +1549,19 @@ OpSwitch: ...@@ -1557,19 +1549,19 @@ OpSwitch:
case ODELETE: case ODELETE:
args := n.List args := n.List
if args == nil { if nodeSeqLen(args) == 0 {
Yyerror("missing arguments to delete") Yyerror("missing arguments to delete")
n.Type = nil n.Type = nil
return return
} }
if args.Next == nil { if nodeSeqLen(args) == 1 {
Yyerror("missing second (key) argument to delete") Yyerror("missing second (key) argument to delete")
n.Type = nil n.Type = nil
return return
} }
if args.Next.Next != nil { if nodeSeqLen(args) != 2 {
Yyerror("too many arguments to delete") Yyerror("too many arguments to delete")
n.Type = nil n.Type = nil
return return
...@@ -1577,33 +1569,36 @@ OpSwitch: ...@@ -1577,33 +1569,36 @@ OpSwitch:
ok |= Etop ok |= Etop
typechecklist(args, Erv) typechecklist(args, Erv)
l := args.N l := nodeSeqFirst(args)
r := args.Next.N r := nodeSeqSecond(args)
if l.Type != nil && l.Type.Etype != TMAP { if l.Type != nil && l.Type.Etype != TMAP {
Yyerror("first argument to delete must be map; have %v", Tconv(l.Type, obj.FmtLong)) Yyerror("first argument to delete must be map; have %v", Tconv(l.Type, obj.FmtLong))
n.Type = nil n.Type = nil
return return
} }
args.Next.N = assignconv(r, l.Type.Down, "delete") it := nodeSeqIterate(args)
it.Next()
*it.P() = assignconv(r, l.Type.Down, "delete")
break OpSwitch break OpSwitch
case OAPPEND: case OAPPEND:
ok |= Erv ok |= Erv
args := n.List args := n.List
if args == nil { if nodeSeqLen(args) == 0 {
Yyerror("missing arguments to append") Yyerror("missing arguments to append")
n.Type = nil n.Type = nil
return return
} }
if count(args) == 1 && !n.Isddd { if nodeSeqLen(args) == 1 && !n.Isddd {
typecheck(&args.N, Erv|Efnstruct) it := nodeSeqIterate(args)
typecheck(it.P(), Erv|Efnstruct)
} else { } else {
typechecklist(args, Erv) typechecklist(args, Erv)
} }
t := args.N.Type t := nodeSeqFirst(args).Type
if t == nil { if t == nil {
n.Type = nil n.Type = nil
return return
...@@ -1618,7 +1613,7 @@ OpSwitch: ...@@ -1618,7 +1613,7 @@ OpSwitch:
n.Type = t n.Type = t
if !Isslice(t) { if !Isslice(t) {
if Isconst(args.N, CTNIL) { if Isconst(nodeSeqFirst(args), CTNIL) {
Yyerror("first argument to append must be typed slice; have untyped nil") Yyerror("first argument to append must be typed slice; have untyped nil")
n.Type = nil n.Type = nil
return return
...@@ -1630,24 +1625,28 @@ OpSwitch: ...@@ -1630,24 +1625,28 @@ OpSwitch:
} }
if n.Isddd { if n.Isddd {
if args.Next == nil { if nodeSeqLen(args) == 1 {
Yyerror("cannot use ... on first argument to append") Yyerror("cannot use ... on first argument to append")
n.Type = nil n.Type = nil
return return
} }
if args.Next.Next != nil { if nodeSeqLen(args) != 2 {
Yyerror("too many arguments to append") Yyerror("too many arguments to append")
n.Type = nil n.Type = nil
return return
} }
if Istype(t.Type, TUINT8) && Istype(args.Next.N.Type, TSTRING) { if Istype(t.Type, TUINT8) && Istype(nodeSeqSecond(args).Type, TSTRING) {
defaultlit(&args.Next.N, Types[TSTRING]) it := nodeSeqIterate(args)
it.Next()
defaultlit(it.P(), Types[TSTRING])
break OpSwitch break OpSwitch
} }
args.Next.N = assignconv(args.Next.N, t.Orig, "append") it := nodeSeqIterate(args)
it.Next()
*it.P() = assignconv(nodeSeqSecond(args), t.Orig, "append")
break OpSwitch break OpSwitch
} }
...@@ -1658,11 +1657,13 @@ OpSwitch: ...@@ -1658,11 +1657,13 @@ OpSwitch:
} }
} }
} else { } else {
for args = args.Next; args != nil; args = args.Next { it := nodeSeqIterate(args)
if args.N.Type == nil { it.Next()
for ; !it.Done(); it.Next() {
if it.N().Type == nil {
continue continue
} }
args.N = assignconv(args.N, t.Type, "append") *it.P() = assignconv(it.N(), t.Type, "append")
} }
} }
...@@ -1671,21 +1672,21 @@ OpSwitch: ...@@ -1671,21 +1672,21 @@ OpSwitch:
case OCOPY: case OCOPY:
ok |= Etop | Erv ok |= Etop | Erv
args := n.List args := n.List
if args == nil || args.Next == nil { if nodeSeqLen(args) == 0 || args.Next == nil {
Yyerror("missing arguments to copy") Yyerror("missing arguments to copy")
n.Type = nil n.Type = nil
return return
} }
if args.Next.Next != nil { if nodeSeqLen(args) > 2 {
Yyerror("too many arguments to copy") Yyerror("too many arguments to copy")
n.Type = nil n.Type = nil
return return
} }
n.Left = args.N n.Left = nodeSeqFirst(args)
n.Right = args.Next.N n.Right = nodeSeqSecond(args)
n.List = nil setNodeSeq(&n.List, nil)
n.Type = Types[TINT] n.Type = Types[TINT]
typecheck(&n.Left, Erv) typecheck(&n.Left, Erv)
typecheck(&n.Right, Erv) typecheck(&n.Right, Erv)
...@@ -1777,16 +1778,16 @@ OpSwitch: ...@@ -1777,16 +1778,16 @@ OpSwitch:
case OMAKE: case OMAKE:
ok |= Erv ok |= Erv
args := n.List args := nodeSeqIterate(n.List)
if args == nil { if args.Len() == 0 {
Yyerror("missing argument to make") Yyerror("missing argument to make")
n.Type = nil n.Type = nil
return return
} }
n.List = nil setNodeSeq(&n.List, nil)
l := args.N l := args.N()
args = args.Next args.Next()
typecheck(&l, Etype) typecheck(&l, Etype)
t := l.Type t := l.Type
if t == nil { if t == nil {
...@@ -1807,19 +1808,19 @@ OpSwitch: ...@@ -1807,19 +1808,19 @@ OpSwitch:
return return
} }
if args == nil { if args.Done() {
Yyerror("missing len argument to make(%v)", t) Yyerror("missing len argument to make(%v)", t)
n.Type = nil n.Type = nil
return return
} }
l = args.N l = args.N()
args = args.Next args.Next()
typecheck(&l, Erv) typecheck(&l, Erv)
var r *Node var r *Node
if args != nil { if !args.Done() {
r = args.N r = args.N()
args = args.Next args.Next()
typecheck(&r, Erv) typecheck(&r, Erv)
} }
...@@ -1842,9 +1843,9 @@ OpSwitch: ...@@ -1842,9 +1843,9 @@ OpSwitch:
n.Op = OMAKESLICE n.Op = OMAKESLICE
case TMAP: case TMAP:
if args != nil { if !args.Done() {
l = args.N l = args.N()
args = args.Next args.Next()
typecheck(&l, Erv) typecheck(&l, Erv)
defaultlit(&l, Types[TINT]) defaultlit(&l, Types[TINT])
if l.Type == nil { if l.Type == nil {
...@@ -1863,9 +1864,9 @@ OpSwitch: ...@@ -1863,9 +1864,9 @@ OpSwitch:
case TCHAN: case TCHAN:
l = nil l = nil
if args != nil { if !args.Done() {
l = args.N l = args.N()
args = args.Next args.Next()
typecheck(&l, Erv) typecheck(&l, Erv)
defaultlit(&l, Types[TINT]) defaultlit(&l, Types[TINT])
if l.Type == nil { if l.Type == nil {
...@@ -1883,7 +1884,7 @@ OpSwitch: ...@@ -1883,7 +1884,7 @@ OpSwitch:
n.Op = OMAKECHAN n.Op = OMAKECHAN
} }
if args != nil { if !args.Done() {
Yyerror("too many arguments to make(%v)", t) Yyerror("too many arguments to make(%v)", t)
n.Op = OMAKE n.Op = OMAKE
n.Type = nil n.Type = nil
...@@ -1896,20 +1897,20 @@ OpSwitch: ...@@ -1896,20 +1897,20 @@ OpSwitch:
case ONEW: case ONEW:
ok |= Erv ok |= Erv
args := n.List args := n.List
if args == nil { if nodeSeqLen(args) == 0 {
Yyerror("missing argument to new") Yyerror("missing argument to new")
n.Type = nil n.Type = nil
return return
} }
l := args.N l := nodeSeqFirst(args)
typecheck(&l, Etype) typecheck(&l, Etype)
t := l.Type t := l.Type
if t == nil { if t == nil {
n.Type = nil n.Type = nil
return return
} }
if args.Next != nil { if nodeSeqLen(args) > 1 {
Yyerror("too many arguments to new(%v)", t) Yyerror("too many arguments to new(%v)", t)
n.Type = nil n.Type = nil
return return
...@@ -1922,12 +1923,12 @@ OpSwitch: ...@@ -1922,12 +1923,12 @@ OpSwitch:
case OPRINT, OPRINTN: case OPRINT, OPRINTN:
ok |= Etop ok |= Etop
typechecklist(n.List, Erv|Eindir) // Eindir: address does not escape typechecklist(n.List, Erv|Eindir) // Eindir: address does not escape
for args := n.List; args != nil; args = args.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
// Special case for print: int constant is int64, not int. // Special case for print: int constant is int64, not int.
if Isconst(args.N, CTINT) { if Isconst(it.N(), CTINT) {
defaultlit(&args.N, Types[TINT64]) defaultlit(it.P(), Types[TINT64])
} else { } else {
defaultlit(&args.N, nil) defaultlit(it.P(), nil)
} }
} }
...@@ -1949,7 +1950,7 @@ OpSwitch: ...@@ -1949,7 +1950,7 @@ OpSwitch:
case ORECOVER: case ORECOVER:
ok |= Erv | Etop ok |= Erv | Etop
if n.List != nil { if nodeSeqLen(n.List) != 0 {
Yyerror("too many arguments to recover") Yyerror("too many arguments to recover")
n.Type = nil n.Type = nil
return return
...@@ -2093,7 +2094,7 @@ OpSwitch: ...@@ -2093,7 +2094,7 @@ OpSwitch:
case ORETURN: case ORETURN:
ok |= Etop ok |= Etop
if count(n.List) == 1 { if nodeSeqLen(n.List) == 1 {
typechecklist(n.List, Erv|Efnstruct) typechecklist(n.List, Erv|Efnstruct)
} else { } else {
typechecklist(n.List, Erv) typechecklist(n.List, Erv)
...@@ -2104,7 +2105,7 @@ OpSwitch: ...@@ -2104,7 +2105,7 @@ OpSwitch:
return return
} }
if Curfn.Type.Outnamed && n.List == nil { if Curfn.Type.Outnamed && nodeSeqLen(n.List) == 0 {
break OpSwitch break OpSwitch
} }
typecheckaste(ORETURN, nil, false, getoutargx(Curfn.Type), n.List, func() string { return "return argument" }) typecheckaste(ORETURN, nil, false, getoutargx(Curfn.Type), n.List, func() string { return "return argument" })
...@@ -2332,22 +2333,22 @@ func onearg(n *Node, f string, args ...interface{}) bool { ...@@ -2332,22 +2333,22 @@ func onearg(n *Node, f string, args ...interface{}) bool {
if n.Left != nil { if n.Left != nil {
return true return true
} }
if n.List == nil { if nodeSeqLen(n.List) == 0 {
p := fmt.Sprintf(f, args...) p := fmt.Sprintf(f, args...)
Yyerror("missing argument to %s: %v", p, n) Yyerror("missing argument to %s: %v", p, n)
return false return false
} }
if n.List.Next != nil { if nodeSeqLen(n.List) > 1 {
p := fmt.Sprintf(f, args...) p := fmt.Sprintf(f, args...)
Yyerror("too many arguments to %s: %v", p, n) Yyerror("too many arguments to %s: %v", p, n)
n.Left = n.List.N n.Left = nodeSeqFirst(n.List)
n.List = nil setNodeSeq(&n.List, nil)
return false return false
} }
n.Left = n.List.N n.Left = nodeSeqFirst(n.List)
n.List = nil setNodeSeq(&n.List, nil)
return true return true
} }
...@@ -2355,26 +2356,26 @@ func twoarg(n *Node) bool { ...@@ -2355,26 +2356,26 @@ func twoarg(n *Node) bool {
if n.Left != nil { if n.Left != nil {
return true return true
} }
if n.List == nil { if nodeSeqLen(n.List) == 0 {
Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), n) Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), n)
return false return false
} }
n.Left = n.List.N n.Left = nodeSeqFirst(n.List)
if n.List.Next == nil { if nodeSeqLen(n.List) == 1 {
Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), n) Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), n)
n.List = nil setNodeSeq(&n.List, nil)
return false return false
} }
if n.List.Next.Next != nil { if nodeSeqLen(n.List) > 2 {
Yyerror("too many arguments to %v - %v", Oconv(int(n.Op), 0), n) Yyerror("too many arguments to %v - %v", Oconv(int(n.Op), 0), n)
n.List = nil setNodeSeq(&n.List, nil)
return false return false
} }
n.Right = n.List.Next.N n.Right = nodeSeqSecond(n.List)
n.List = nil setNodeSeq(&n.List, nil)
return true return true
} }
...@@ -2915,8 +2916,8 @@ func typecheckcomplit(np **Node) { ...@@ -2915,8 +2916,8 @@ func typecheckcomplit(np **Node) {
}() }()
if n.Right == nil { if n.Right == nil {
if n.List != nil { if nodeSeqLen(n.List) != 0 {
setlineno(n.List.N) setlineno(nodeSeqFirst(n.List))
} }
Yyerror("missing type in composite literal") Yyerror("missing type in composite literal")
n.Type = nil n.Type = nil
...@@ -2966,22 +2967,22 @@ func typecheckcomplit(np **Node) { ...@@ -2966,22 +2967,22 @@ func typecheckcomplit(np **Node) {
case TARRAY: case TARRAY:
// Only allocate hash if there are some key/value pairs. // Only allocate hash if there are some key/value pairs.
var hash map[int64]*Node var hash map[int64]*Node
for ll := n.List; ll != nil; ll = ll.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
if ll.N.Op == OKEY { if it.N().Op == OKEY {
hash = make(map[int64]*Node) hash = make(map[int64]*Node)
break break
} }
} }
length := int64(0) length := int64(0)
i := 0 i := 0
for ll := n.List; ll != nil; ll = ll.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
l := ll.N l := it.N()
setlineno(l) setlineno(l)
if l.Op != OKEY { if l.Op != OKEY {
l = Nod(OKEY, Nodintconst(int64(i)), l) l = Nod(OKEY, Nodintconst(int64(i)), l)
l.Left.Type = Types[TINT] l.Left.Type = Types[TINT]
l.Left.Typecheck = 1 l.Left.Typecheck = 1
ll.N = l *it.P() = l
} }
typecheck(&l.Left, Erv) typecheck(&l.Left, Erv)
...@@ -3024,11 +3025,11 @@ func typecheckcomplit(np **Node) { ...@@ -3024,11 +3025,11 @@ func typecheckcomplit(np **Node) {
case TMAP: case TMAP:
hash := make(map[uint32][]*Node) hash := make(map[uint32][]*Node)
var l *Node var l *Node
for ll := n.List; ll != nil; ll = ll.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
l = ll.N l = it.N()
setlineno(l) setlineno(l)
if l.Op != OKEY { if l.Op != OKEY {
typecheck(&ll.N, Erv) typecheck(it.P(), Erv)
Yyerror("missing key in map literal") Yyerror("missing key in map literal")
continue continue
} }
...@@ -3053,14 +3054,14 @@ func typecheckcomplit(np **Node) { ...@@ -3053,14 +3054,14 @@ func typecheckcomplit(np **Node) {
case TSTRUCT: case TSTRUCT:
bad := 0 bad := 0
if n.List != nil && nokeys(n.List) { if nodeSeqLen(n.List) != 0 && nokeys(n.List) {
// simple list of variables // simple list of variables
f := t.Type f := t.Type
var s *Sym var s *Sym
for ll := n.List; ll != nil; ll = ll.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
setlineno(ll.N) setlineno(it.N())
typecheck(&ll.N, Erv) typecheck(it.P(), Erv)
if f == nil { if f == nil {
if bad == 0 { if bad == 0 {
Yyerror("too many values in struct initializer") Yyerror("too many values in struct initializer")
...@@ -3075,11 +3076,11 @@ func typecheckcomplit(np **Node) { ...@@ -3075,11 +3076,11 @@ func typecheckcomplit(np **Node) {
} }
// No pushtype allowed here. Must name fields for that. // No pushtype allowed here. Must name fields for that.
ll.N = assignconv(ll.N, f.Type, "field value") *it.P() = assignconv(it.N(), f.Type, "field value")
ll.N = Nod(OKEY, newname(f.Sym), ll.N) *it.P() = Nod(OKEY, newname(f.Sym), it.N())
ll.N.Left.Type = f it.N().Left.Type = f
ll.N.Left.Typecheck = 1 it.N().Left.Typecheck = 1
f = f.Down f = f.Down
} }
...@@ -3094,15 +3095,15 @@ func typecheckcomplit(np **Node) { ...@@ -3094,15 +3095,15 @@ func typecheckcomplit(np **Node) {
var f *Type var f *Type
var l *Node var l *Node
var s1 *Sym var s1 *Sym
for ll := n.List; ll != nil; ll = ll.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
l = ll.N l = it.N()
setlineno(l) setlineno(l)
if l.Op != OKEY { if l.Op != OKEY {
if bad == 0 { if bad == 0 {
Yyerror("mixture of field:value and value initializers") Yyerror("mixture of field:value and value initializers")
} }
bad++ bad++
typecheck(&ll.N, Erv) typecheck(it.P(), Erv)
continue continue
} }
...@@ -3313,19 +3314,20 @@ func checkassignto(src *Type, dst *Node) { ...@@ -3313,19 +3314,20 @@ func checkassignto(src *Type, dst *Node) {
} }
func typecheckas2(n *Node) { func typecheckas2(n *Node) {
for ll := n.List; ll != nil; ll = ll.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
// delicate little dance. // delicate little dance.
ll.N = resolve(ll.N) *it.P() = resolve(it.N())
if ll.N.Name == nil || ll.N.Name.Defn != n || ll.N.Name.Param.Ntype != nil { if it.N().Name == nil || it.N().Name.Defn != n || it.N().Name.Param.Ntype != nil {
typecheck(&ll.N, Erv|Easgn) typecheck(it.P(), Erv|Easgn)
} }
} }
cl := count(n.List) cl := nodeSeqLen(n.List)
cr := count(n.Rlist) cr := nodeSeqLen(n.Rlist)
if cl > 1 && cr == 1 { if cl > 1 && cr == 1 {
typecheck(&n.Rlist.N, Erv|Efnstruct) it := nodeSeqIterate(n.Rlist)
typecheck(it.P(), Erv|Efnstruct)
} else { } else {
typechecklist(n.Rlist, Erv) typechecklist(n.Rlist, Erv)
} }
...@@ -3335,23 +3337,24 @@ func typecheckas2(n *Node) { ...@@ -3335,23 +3337,24 @@ func typecheckas2(n *Node) {
var r *Node var r *Node
if cl == cr { if cl == cr {
// easy // easy
ll := n.List llit := nodeSeqIterate(n.List)
lr := n.Rlist lrit := nodeSeqIterate(n.Rlist)
for ; ll != nil; ll, lr = ll.Next, lr.Next { for llit = nodeSeqIterate(n.List); !llit.Done(); llit.Next() {
if ll.N.Type != nil && lr.N.Type != nil { if llit.N().Type != nil && lrit.N().Type != nil {
lr.N = assignconv(lr.N, ll.N.Type, "assignment") *lrit.P() = assignconv(lrit.N(), llit.N().Type, "assignment")
} }
if ll.N.Name != nil && ll.N.Name.Defn == n && ll.N.Name.Param.Ntype == nil { if llit.N().Name != nil && llit.N().Name.Defn == n && llit.N().Name.Param.Ntype == nil {
defaultlit(&lr.N, nil) defaultlit(lrit.P(), nil)
ll.N.Type = lr.N.Type llit.N().Type = lrit.N().Type
} }
lrit.Next()
} }
goto out goto out
} }
l = n.List.N l = nodeSeqFirst(n.List)
r = n.Rlist.N r = nodeSeqFirst(n.Rlist)
// x,y,z = f() // x,y,z = f()
if cr == 1 { if cr == 1 {
...@@ -3370,12 +3373,12 @@ func typecheckas2(n *Node) { ...@@ -3370,12 +3373,12 @@ func typecheckas2(n *Node) {
n.Op = OAS2FUNC n.Op = OAS2FUNC
var s Iter var s Iter
t := Structfirst(&s, &r.Type) t := Structfirst(&s, &r.Type)
for ll := n.List; ll != nil; ll = ll.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
if t.Type != nil && ll.N.Type != nil { if t.Type != nil && it.N().Type != nil {
checkassignto(t.Type, ll.N) checkassignto(t.Type, it.N())
} }
if ll.N.Name != nil && ll.N.Name.Defn == n && ll.N.Name.Param.Ntype == nil { if it.N().Name != nil && it.N().Name.Defn == n && it.N().Name.Param.Ntype == nil {
ll.N.Type = t.Type it.N().Type = t.Type
} }
t = structnext(&s) t = structnext(&s)
} }
...@@ -3409,7 +3412,7 @@ func typecheckas2(n *Node) { ...@@ -3409,7 +3412,7 @@ func typecheckas2(n *Node) {
if l.Name != nil && l.Name.Defn == n { if l.Name != nil && l.Name.Defn == n {
l.Type = r.Type l.Type = r.Type
} }
l := n.List.Next.N l := nodeSeqSecond(n.List)
if l.Type != nil && l.Type.Etype != TBOOL { if l.Type != nil && l.Type.Etype != TBOOL {
checkassignto(Types[TBOOL], l) checkassignto(Types[TBOOL], l)
} }
...@@ -3427,9 +3430,9 @@ mismatch: ...@@ -3427,9 +3430,9 @@ mismatch:
out: out:
n.Typecheck = 1 n.Typecheck = 1
for ll := n.List; ll != nil; ll = ll.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
if ll.N.Typecheck == 0 { if it.N().Typecheck == 0 {
typecheck(&ll.N, Erv|Easgn) typecheck(it.P(), Erv|Easgn)
} }
} }
} }
...@@ -3462,23 +3465,23 @@ func stringtoarraylit(np **Node) { ...@@ -3462,23 +3465,23 @@ func stringtoarraylit(np **Node) {
} }
s := n.Left.Val().U.(string) s := n.Left.Val().U.(string)
var l *NodeList var l []*Node
if n.Type.Type.Etype == TUINT8 { if n.Type.Type.Etype == TUINT8 {
// []byte // []byte
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
l = list(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(s[0])))) l = append(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(s[0]))))
} }
} else { } else {
// []rune // []rune
i := 0 i := 0
for _, r := range s { for _, r := range s {
l = list(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(r)))) l = append(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(r))))
i++ i++
} }
} }
nn := Nod(OCOMPLIT, nil, typenod(n.Type)) nn := Nod(OCOMPLIT, nil, typenod(n.Type))
nn.List = l setNodeSeq(&nn.List, l)
typecheck(&nn, Erv) typecheck(&nn, Erv)
*np = nn *np = nn
} }
...@@ -3880,43 +3883,16 @@ func markbreak(n *Node, implicit *Node) { ...@@ -3880,43 +3883,16 @@ func markbreak(n *Node, implicit *Node) {
markbreak(n.Right, implicit) markbreak(n.Right, implicit)
markbreaklist(n.Ninit, implicit) markbreaklist(n.Ninit, implicit)
markbreakslice(n.Nbody.Slice(), implicit) markbreaklist(n.Nbody, implicit)
markbreaklist(n.List, implicit) markbreaklist(n.List, implicit)
markbreaklist(n.Rlist, implicit) markbreaklist(n.Rlist, implicit)
} }
} }
func markbreaklist(l *NodeList, implicit *Node) { func markbreaklist(l nodesOrNodeList, implicit *Node) {
var n *Node for it := nodeSeqIterate(l); !it.Done(); it.Next() {
var lab *Label n := it.N()
if n.Op == OLABEL && it.Len() > 1 && n.Name.Defn == nodeSeqSlice(it.Seq())[1] {
for ; l != nil; l = l.Next {
n = l.N
if n.Op == OLABEL && l.Next != nil && n.Name.Defn == l.Next.N {
switch n.Name.Defn.Op {
case OFOR,
OSWITCH,
OTYPESW,
OSELECT,
ORANGE:
lab = new(Label)
lab.Def = n.Name.Defn
n.Left.Sym.Label = lab
markbreak(n.Name.Defn, n.Name.Defn)
n.Left.Sym.Label = nil
l = l.Next
continue
}
}
markbreak(n, implicit)
}
}
func markbreakslice(l []*Node, implicit *Node) {
for i := 0; i < len(l); i++ {
n := l[i]
if n.Op == OLABEL && i+1 < len(l) && n.Name.Defn == l[i+1] {
switch n.Name.Defn.Op { switch n.Name.Defn.Op {
case OFOR, OSWITCH, OTYPESW, OSELECT, ORANGE: case OFOR, OSWITCH, OTYPESW, OSELECT, ORANGE:
lab := new(Label) lab := new(Label)
...@@ -3924,7 +3900,7 @@ func markbreakslice(l []*Node, implicit *Node) { ...@@ -3924,7 +3900,7 @@ func markbreakslice(l []*Node, implicit *Node) {
n.Left.Sym.Label = lab n.Left.Sym.Label = lab
markbreak(n.Name.Defn, n.Name.Defn) markbreak(n.Name.Defn, n.Name.Defn)
n.Left.Sym.Label = nil n.Left.Sym.Label = nil
i++ it.Next()
continue continue
} }
} }
...@@ -3991,11 +3967,11 @@ func (n *Node) isterminating() bool { ...@@ -3991,11 +3967,11 @@ func (n *Node) isterminating() bool {
return false return false
} }
def := 0 def := 0
for l := n.List; l != nil; l = l.Next { for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
if !l.N.Nbody.isterminating() { if !it.N().Nbody.isterminating() {
return false return false
} }
if l.N.List == nil { // default if nodeSeqLen(it.N().List) == 0 { // default
def = 1 def = 1
} }
} }
...@@ -4011,7 +3987,7 @@ func (n *Node) isterminating() bool { ...@@ -4011,7 +3987,7 @@ func (n *Node) isterminating() bool {
func checkreturn(fn *Node) { func checkreturn(fn *Node) {
if fn.Type.Outtuple != 0 && len(fn.Nbody.Slice()) != 0 { if fn.Type.Outtuple != 0 && len(fn.Nbody.Slice()) != 0 {
markbreakslice(fn.Nbody.Slice(), nil) markbreaklist(fn.Nbody, nil)
if !fn.Nbody.isterminating() { if !fn.Nbody.isterminating() {
yyerrorl(fn.Func.Endlineno, "missing return at end of function") yyerrorl(fn.Func.Endlineno, "missing return at end of function")
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment