From 65c4b55aba2ccbc26fcd143c29f6014b91616897 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 4 Mar 2016 17:28:07 -0800 Subject: [PATCH] cmd/compile: convert subr, swt, typecheck to nodeSeq Passes toolstash -cmp. Update #14473. Change-Id: I836197810405cde72cbb49fef7e163a517601f9c Reviewed-on: https://go-review.googlesource.com/20242 Reviewed-by: David Crawshaw --- src/cmd/compile/internal/gc/dcl.go | 10 +- src/cmd/compile/internal/gc/subr.go | 56 ++-- src/cmd/compile/internal/gc/swt.go | 128 ++++----- src/cmd/compile/internal/gc/syntax.go | 4 +- src/cmd/compile/internal/gc/typecheck.go | 334 +++++++++++------------ 5 files changed, 254 insertions(+), 278 deletions(-) diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index 5cb5e8b77b..94c4bebec1 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -297,19 +297,19 @@ func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList { lastconst = cl lasttype = t } - cl = listtreecopy(cl, lno) + clcopy := listtreecopy(cl, lno) var v *Node var c *Node var vv *NodeList for ; vl != nil; vl = vl.Next { - if cl == nil { + if len(clcopy) == 0 { Yyerror("missing value in const declaration") break } - c = cl.N - cl = cl.Next + c = clcopy[0] + clcopy = clcopy[1:] v = vl.N v.Op = OLITERAL @@ -321,7 +321,7 @@ func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList { vv = list(vv, Nod(ODCLCONST, v, nil)) } - if cl != nil { + if len(clcopy) != 0 { Yyerror("extra expression in const declaration") } iota_ += 1 diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go index f828bd268e..24ee47bbc4 100644 --- a/src/cmd/compile/internal/gc/subr.go +++ b/src/cmd/compile/internal/gc/subr.go @@ -536,7 +536,7 @@ func treecopy(n *Node, lineno int32) *Node { m.Orig = m m.Left = treecopy(n.Left, lineno) m.Right = treecopy(n.Right, lineno) - m.List = listtreecopy(n.List, lineno) + setNodeSeq(&m.List, listtreecopy(n.List, lineno)) if lineno != 0 { m.Lineno = lineno } @@ -1393,7 +1393,7 @@ func ullmancalc(n *Node) { var ul int var ur int - if n.Ninit != nil { + if nodeSeqLen(n.Ninit) != 0 { ul = UINF goto out } @@ -2014,13 +2014,13 @@ func expandmeth(t *Type) { } // 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 a *Node var n *Node var buf string - var args *NodeList + var args []*Node gen := 0 for t := Structfirst(&savet, tl); t != nil; t = structnext(&savet) { n = nil @@ -2038,7 +2038,7 @@ func structargs(tl **Type, mustname int) *NodeList { if n != nil { n.Isddd = t.Isddd } - args = list(args, a) + args = append(args, a) } return args @@ -2091,7 +2091,7 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { out := structargs(Getoutarg(method.Type), 0) t := Nod(OTFUNC, nil, nil) - l := list1(this) + l := []*Node{this} if iface != 0 && rcvr.Width < Types[Tptr].Width { // Building method for interface table and receiver // is smaller than the single pointer-sized word @@ -2103,11 +2103,11 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { tpad.Type = Types[TUINT8] tpad.Bound = Types[Tptr].Width - rcvr.Width pad := Nod(ODCLFIELD, newname(Lookup(".pad")), typenod(tpad)) - l = list(l, pad) + l = append(l, pad) } - t.List = concat(l, in) - t.Rlist = out + setNodeSeq(&t.List, append(l, in...)) + setNodeSeq(&t.Rlist, out) fn := Nod(ODCLFUNC, nil, nil) fn.Func.Nname = newname(newnam) @@ -2117,12 +2117,12 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { funchdr(fn) // arg list - var args *NodeList + var args []*Node isddd := false - for l := in; l != nil; l = l.Next { - args = list(args, l.N.Left) - isddd = l.N.Left.Isddd + for _, n := range in { + args = append(args, n.Left) + isddd = n.Left.Isddd } methodrcvr := getthisx(method.Type).Type.Type @@ -2136,17 +2136,17 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { // these strings are already in the reflect tables, // so no space cost to use them here. - var l *NodeList + var l []*Node var v Val 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 - l = list(l, nodlit(v)) + l = append(l, nodlit(v)) 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.List = l + setNodeSeq(&call.List, l) n.Nbody.Set([]*Node{call}) fn.Nbody.Append(n) } @@ -2169,11 +2169,11 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { } else { fn.Func.Wrapper = true // ignore frame for panic+recover matching call := Nod(OCALL, dot, nil) - call.List = args + setNodeSeq(&call.List, args) call.Isddd = isddd if method.Type.Outtuple > 0 { n := Nod(ORETURN, nil, nil) - n.List = list1(call) + setNodeSeq(&n.List, []*Node{call}) call = n } @@ -2207,10 +2207,10 @@ func hashmem(t *Type) *Node { n := newname(sym) n.Class = PFUNC tfn := Nod(OTFUNC, nil, nil) - tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t)))) - tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) - tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) - tfn.Rlist = list(tfn.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) + appendNodeSeqNode(&tfn.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t)))) + appendNodeSeqNode(&tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) + appendNodeSeqNode(&tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) + appendNodeSeqNode(&tfn.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) typecheck(&tfn, Etype) n.Type = tfn.Type return n @@ -2354,10 +2354,10 @@ func Simsimtype(t *Type) EType { return et } -func listtreecopy(l *NodeList, lineno int32) *NodeList { - var out *NodeList - for ; l != nil; l = l.Next { - out = list(out, treecopy(l.N, lineno)) +func listtreecopy(l nodesOrNodeList, lineno int32) []*Node { + var out []*Node + for it := nodeSeqIterate(l); !it.Done(); it.Next() { + out = append(out, treecopy(it.N(), lineno)) } return out } diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go index 4f3d3dde49..9870614f72 100644 --- a/src/cmd/compile/internal/gc/swt.go +++ b/src/cmd/compile/internal/gc/swt.go @@ -105,11 +105,10 @@ func typecheckswitch(n *Node) { n.Type = t var def *Node - var ll *NodeList - for l := n.List; l != nil; l = l.Next { - ncase := l.N + for it := nodeSeqIterate(n.List); !it.Done(); it.Next() { + ncase := it.N() setlineno(n) - if ncase.List == nil { + if nodeSeqLen(ncase.List) == 0 { // default if def != nil { Yyerror("multiple defaults in switch (first at %v)", def.Line()) @@ -117,30 +116,30 @@ func typecheckswitch(n *Node) { 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 { + for it2 := nodeSeqIterate(ncase.List); !it2.Done(); it2.Next() { + setlineno(it2.N()) + typecheck(it2.P(), Erv|Etype) + if it2.N().Type == nil || t == nil { continue } setlineno(ncase) switch top { // expression switch case Erv: - defaultlit(&ll.N, t) + defaultlit(it2.P(), 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: + case it2.N().Op == OTYPE: + Yyerror("type %v is not an expression", it2.N().Type) + case it2.N().Type != nil && assignop(it2.N().Type, t, nil) == 0 && assignop(t, it2.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) + Yyerror("invalid case %v in switch on %v (mismatched types %v and %v)", it2.N(), n.Left, it2.N().Type, t) } 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): - Yyerror("invalid case %v in switch (can only compare %s %v to nil)", ll.N, nilonly, n.Left) - case Isinter(t) && !Isinter(ll.N.Type) && algtype1(ll.N.Type, nil) == ANOEQ: - Yyerror("invalid case %v in switch (incomparable type)", Nconv(ll.N, obj.FmtLong)) + case nilonly != "" && !isnil(it2.N()): + Yyerror("invalid case %v in switch (can only compare %s %v to nil)", it2.N(), nilonly, n.Left) + case Isinter(t) && !Isinter(it2.N().Type) && algtype1(it2.N().Type, nil) == ANOEQ: + Yyerror("invalid case %v in switch (incomparable type)", Nconv(it2.N(), obj.FmtLong)) } // type switch @@ -148,16 +147,16 @@ func typecheckswitch(n *Node) { 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)) + case it2.N().Op == OLITERAL && Istype(it2.N().Type, TNIL): + case it2.N().Op != OTYPE && it2.N().Type != nil: // should this be ||? + Yyerror("%v is not a type", Nconv(it2.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): + *it2.P() = n.Left.Right + case it2.N().Type.Etype != TINTER && t.Etype == TINTER && !implements(it2.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)) + 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 { - 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) { } 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) { + ll := ncase.List + if nodeSeqLen(ncase.Rlist) != 0 { + nvar := nodeSeqFirst(ncase.Rlist) + if nodeSeqLen(ll) == 1 && nodeSeqFirst(ll).Type != nil && !Istype(nodeSeqFirst(ll).Type, TNIL) { // single entry type switch - nvar.Name.Param.Ntype = typenod(ll.N.Type) + nvar.Name.Param.Ntype = typenod(nodeSeqFirst(ll).Type) } else { // multiple entry type switch or default nvar.Name.Param.Ntype = typenod(n.Type) } 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) { // enumerate the cases, and lop off the default case cc := caseClauses(sw, s.kind) - sw.List = nil + setNodeSeq(&sw.List, nil) var def *Node if len(cc) > 0 && cc[0].typ == caseKindDefault { def = cc[0].node.Right @@ -326,7 +326,7 @@ func (s *exprSwitch) walkCases(cc []*caseClause) *Node { } typecheck(&a.Left, Erv) 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 } @@ -334,28 +334,28 @@ func (s *exprSwitch) walkCases(cc []*caseClause) *Node { // 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 { + if nodeSeqLen(sw.List) == 0 { return } lno := setlineno(sw) - var cas *NodeList // cases - var stat []*Node // statements - var def *Node // defaults + var cas []*Node // cases + var stat []*Node // statements + var def *Node // defaults br := Nod(OBREAK, nil, nil) - for l := sw.List; l != nil; l = l.Next { - n := l.N + for it := nodeSeqIterate(sw.List); !it.Done(); it.Next() { + n := it.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 + needvar := nodeSeqLen(n.List) != 1 || nodeSeqFirst(n.List).Op == OLITERAL jmp := Nod(OGOTO, newCaseLabel(), nil) - if n.List == nil { + if nodeSeqLen(n.List) == 0 { if def != nil { Yyerror("more than one default case") } @@ -364,24 +364,24 @@ func casebody(sw *Node, typeswvar *Node) { def = n } - if n.List != nil && n.List.Next == nil { + if nodeSeqLen(n.List) == 1 { // one case -- reuse OCASE node - n.Left = n.List.N + n.Left = nodeSeqFirst(n.List) n.Right = jmp - n.List = nil - cas = list(cas, n) + setNodeSeq(&n.List, nil) + cas = append(cas, n) } else { // expand multi-valued cases - for lc := n.List; lc != nil; lc = lc.Next { - cas = list(cas, Nod(OCASE, lc.N, jmp)) + for lcit := nodeSeqIterate(n.List); !lcit.Done(); lcit.Next() { + cas = append(cas, Nod(OCASE, lcit.N(), jmp)) } } 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{ - Nod(ODCL, n.Rlist.N, nil), - Nod(OAS, n.Rlist.N, typeswvar), + Nod(ODCL, nodeSeqFirst(n.Rlist), nil), + Nod(OAS, nodeSeqFirst(n.Rlist), typeswvar), } typecheckslice(l, Etop) stat = append(stat, l...) @@ -396,7 +396,7 @@ func casebody(sw *Node, typeswvar *Node) { Yyerror("cannot fallthrough in type switch") } - if l.Next == nil { + if it.Len() <= 1 { setlineno(last) Yyerror("cannot fallthrough final case in switch") } @@ -409,10 +409,10 @@ func casebody(sw *Node, typeswvar *Node) { stat = append(stat, br) if def != nil { - cas = list(cas, def) + cas = append(cas, def) } - sw.List = cas + setNodeSeq(&sw.List, cas) sw.Nbody.Set(stat) lineno = lno } @@ -432,8 +432,8 @@ func newCaseLabel() *Node { // 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 + for it := nodeSeqIterate(sw.List); !it.Done(); it.Next() { + n := it.N() c := new(caseClause) cc = append(cc, c) c.ordinal = len(cc) @@ -518,7 +518,7 @@ func (s *typeSwitch) walk(sw *Node) { sw.Left = nil if cond == nil { - sw.List = nil + setNodeSeq(&sw.List, nil) return } if cond.Right == nil { @@ -552,7 +552,7 @@ func (s *typeSwitch) walk(sw *Node) { casebody(sw, s.facename) cc := caseClauses(sw, switchKindType) - sw.List = nil + setNodeSeq(&sw.List, nil) var def *Node if len(cc) > 0 && cc[0].typ == caseKindDefault { def = cc[0].node.Right @@ -588,7 +588,7 @@ func (s *typeSwitch) walk(sw *Node) { i.Nbody.Set([]*Node{Nod(OGOTO, lbl, nil)}) // Wrap default case with label. 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 } typecheck(&i.Left, Erv) @@ -669,7 +669,7 @@ func (s *typeSwitch) walk(sw *Node) { if nerrors == 0 { cas = append(cas, def) sw.Nbody.Set(append(cas, sw.Nbody.Slice()...)) - sw.List = nil + setNodeSeq(&sw.List, nil) walkstmtlist(sw.Nbody) } } @@ -679,11 +679,11 @@ func (s *typeSwitch) walk(sw *Node) { func (s *typeSwitch) typeone(t *Node) *Node { var name *Node var init *NodeList - if t.Rlist == nil { + if nodeSeqLen(t.Rlist) == 0 { name = nblank typecheck(&nblank, Erv|Easgn) } else { - name = t.Rlist.N + name = nodeSeqFirst(t.Rlist) init = list1(Nod(ODCL, name, nil)) a := Nod(OAS, name, nil) typecheck(&a, Etop) @@ -691,10 +691,10 @@ func (s *typeSwitch) typeone(t *Node) *Node { } 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.Type = t.Left.Type // interface.(type) - a.Rlist = list1(b) + setNodeSeq(&a.Rlist, []*Node{b}) typecheck(&a, Etop) init = list(init, a) @@ -729,7 +729,7 @@ func (s *typeSwitch) walkCases(cc []*caseClause) *Node { a.Left = Nod(OLE, s.hashname, Nodintconst(int64(cc[half-1].hash))) typecheck(&a.Left, Erv) 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 } diff --git a/src/cmd/compile/internal/gc/syntax.go b/src/cmd/compile/internal/gc/syntax.go index 3cc01717ad..4c058e139f 100644 --- a/src/cmd/compile/internal/gc/syntax.go +++ b/src/cmd/compile/internal/gc/syntax.go @@ -391,12 +391,12 @@ func list1(n *Node) *NodeList { if n == nil { return nil } - if n.Op == OBLOCK && n.Ninit == nil { + if n.Op == OBLOCK && nodeSeqLen(n.Ninit) == 0 { // Flatten list and steal storage. // Poison pointer to catch errant uses. l := n.List - n.List = nil + setNodeSeq(&n.List, nil) return l } diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index ec3229400b..50b5698b74 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -217,21 +217,12 @@ func callrecv(n *Node) bool { 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 { - for ; l != nil; l = l.Next { - if callrecv(l.N) { - return true - } - } - return false -} - -func callrecvslice(l []*Node) bool { - for _, n := range l { - if callrecv(n) { +func callrecvlist(l nodesOrNodeList) bool { + for it := nodeSeqIterate(l); !it.Done(); it.Next() { + if callrecv(it.N()) { return true } } @@ -440,7 +431,7 @@ OpSwitch: n.Type = nil return } - n.List = nil + setNodeSeq(&n.List, nil) case OTINTER: ok |= Etype @@ -714,14 +705,14 @@ OpSwitch: n.Op = OADDSTR if l.Op == OADDSTR { - n.List = l.List + setNodeSeq(&n.List, l.List) } else { - n.List = list1(l) + setNodeSeq(&n.List, []*Node{l}) } if r.Op == OADDSTR { - n.List = concat(n.List, r.List) + appendNodeSeq(&n.List, r.List) } else { - n.List = list(n.List, r) + appendNodeSeqNode(&n.List, r) } n.Left = nil n.Right = nil @@ -1298,8 +1289,9 @@ OpSwitch: return } - if count(n.List) == 1 && !n.Isddd { - typecheck(&n.List.N, Erv|Efnstruct) + if nodeSeqLen(n.List) == 1 && !n.Isddd { + it := nodeSeqIterate(n.List) + typecheck(it.P(), Erv|Efnstruct) } else { typechecklist(n.List, Erv) } @@ -1455,22 +1447,22 @@ OpSwitch: ok |= Erv var r *Node var l *Node - if count(n.List) == 1 { + if nodeSeqLen(n.List) == 1 { 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") n.Type = nil return } - t := n.List.N.Left.Type + t := nodeSeqFirst(n.List).Left.Type 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 return } - t = n.List.N.Type.Type + t = nodeSeqFirst(n.List).Type.Type l = t.Nname r = t.Down.Nname } else { @@ -1557,19 +1549,19 @@ OpSwitch: case ODELETE: args := n.List - if args == nil { + if nodeSeqLen(args) == 0 { Yyerror("missing arguments to delete") n.Type = nil return } - if args.Next == nil { + if nodeSeqLen(args) == 1 { Yyerror("missing second (key) argument to delete") n.Type = nil return } - if args.Next.Next != nil { + if nodeSeqLen(args) != 2 { Yyerror("too many arguments to delete") n.Type = nil return @@ -1577,33 +1569,36 @@ OpSwitch: ok |= Etop typechecklist(args, Erv) - l := args.N - r := args.Next.N + l := nodeSeqFirst(args) + r := nodeSeqSecond(args) if l.Type != nil && l.Type.Etype != TMAP { Yyerror("first argument to delete must be map; have %v", Tconv(l.Type, obj.FmtLong)) n.Type = nil 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 case OAPPEND: ok |= Erv args := n.List - if args == nil { + if nodeSeqLen(args) == 0 { Yyerror("missing arguments to append") n.Type = nil return } - if count(args) == 1 && !n.Isddd { - typecheck(&args.N, Erv|Efnstruct) + if nodeSeqLen(args) == 1 && !n.Isddd { + it := nodeSeqIterate(args) + typecheck(it.P(), Erv|Efnstruct) } else { typechecklist(args, Erv) } - t := args.N.Type + t := nodeSeqFirst(args).Type if t == nil { n.Type = nil return @@ -1618,7 +1613,7 @@ OpSwitch: n.Type = 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") n.Type = nil return @@ -1630,24 +1625,28 @@ OpSwitch: } if n.Isddd { - if args.Next == nil { + if nodeSeqLen(args) == 1 { Yyerror("cannot use ... on first argument to append") n.Type = nil return } - if args.Next.Next != nil { + if nodeSeqLen(args) != 2 { Yyerror("too many arguments to append") n.Type = nil return } - if Istype(t.Type, TUINT8) && Istype(args.Next.N.Type, TSTRING) { - defaultlit(&args.Next.N, Types[TSTRING]) + if Istype(t.Type, TUINT8) && Istype(nodeSeqSecond(args).Type, TSTRING) { + it := nodeSeqIterate(args) + it.Next() + defaultlit(it.P(), Types[TSTRING]) 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 } @@ -1658,11 +1657,13 @@ OpSwitch: } } } else { - for args = args.Next; args != nil; args = args.Next { - if args.N.Type == nil { + it := nodeSeqIterate(args) + it.Next() + for ; !it.Done(); it.Next() { + if it.N().Type == nil { continue } - args.N = assignconv(args.N, t.Type, "append") + *it.P() = assignconv(it.N(), t.Type, "append") } } @@ -1671,21 +1672,21 @@ OpSwitch: case OCOPY: ok |= Etop | Erv args := n.List - if args == nil || args.Next == nil { + if nodeSeqLen(args) == 0 || args.Next == nil { Yyerror("missing arguments to copy") n.Type = nil return } - if args.Next.Next != nil { + if nodeSeqLen(args) > 2 { Yyerror("too many arguments to copy") n.Type = nil return } - n.Left = args.N - n.Right = args.Next.N - n.List = nil + n.Left = nodeSeqFirst(args) + n.Right = nodeSeqSecond(args) + setNodeSeq(&n.List, nil) n.Type = Types[TINT] typecheck(&n.Left, Erv) typecheck(&n.Right, Erv) @@ -1777,16 +1778,16 @@ OpSwitch: case OMAKE: ok |= Erv - args := n.List - if args == nil { + args := nodeSeqIterate(n.List) + if args.Len() == 0 { Yyerror("missing argument to make") n.Type = nil return } - n.List = nil - l := args.N - args = args.Next + setNodeSeq(&n.List, nil) + l := args.N() + args.Next() typecheck(&l, Etype) t := l.Type if t == nil { @@ -1807,19 +1808,19 @@ OpSwitch: return } - if args == nil { + if args.Done() { Yyerror("missing len argument to make(%v)", t) n.Type = nil return } - l = args.N - args = args.Next + l = args.N() + args.Next() typecheck(&l, Erv) var r *Node - if args != nil { - r = args.N - args = args.Next + if !args.Done() { + r = args.N() + args.Next() typecheck(&r, Erv) } @@ -1842,9 +1843,9 @@ OpSwitch: n.Op = OMAKESLICE case TMAP: - if args != nil { - l = args.N - args = args.Next + if !args.Done() { + l = args.N() + args.Next() typecheck(&l, Erv) defaultlit(&l, Types[TINT]) if l.Type == nil { @@ -1863,9 +1864,9 @@ OpSwitch: case TCHAN: l = nil - if args != nil { - l = args.N - args = args.Next + if !args.Done() { + l = args.N() + args.Next() typecheck(&l, Erv) defaultlit(&l, Types[TINT]) if l.Type == nil { @@ -1883,7 +1884,7 @@ OpSwitch: n.Op = OMAKECHAN } - if args != nil { + if !args.Done() { Yyerror("too many arguments to make(%v)", t) n.Op = OMAKE n.Type = nil @@ -1896,20 +1897,20 @@ OpSwitch: case ONEW: ok |= Erv args := n.List - if args == nil { + if nodeSeqLen(args) == 0 { Yyerror("missing argument to new") n.Type = nil return } - l := args.N + l := nodeSeqFirst(args) typecheck(&l, Etype) t := l.Type if t == nil { n.Type = nil return } - if args.Next != nil { + if nodeSeqLen(args) > 1 { Yyerror("too many arguments to new(%v)", t) n.Type = nil return @@ -1922,12 +1923,12 @@ OpSwitch: case OPRINT, OPRINTN: ok |= Etop 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. - if Isconst(args.N, CTINT) { - defaultlit(&args.N, Types[TINT64]) + if Isconst(it.N(), CTINT) { + defaultlit(it.P(), Types[TINT64]) } else { - defaultlit(&args.N, nil) + defaultlit(it.P(), nil) } } @@ -1949,7 +1950,7 @@ OpSwitch: case ORECOVER: ok |= Erv | Etop - if n.List != nil { + if nodeSeqLen(n.List) != 0 { Yyerror("too many arguments to recover") n.Type = nil return @@ -2093,7 +2094,7 @@ OpSwitch: case ORETURN: ok |= Etop - if count(n.List) == 1 { + if nodeSeqLen(n.List) == 1 { typechecklist(n.List, Erv|Efnstruct) } else { typechecklist(n.List, Erv) @@ -2104,7 +2105,7 @@ OpSwitch: return } - if Curfn.Type.Outnamed && n.List == nil { + if Curfn.Type.Outnamed && nodeSeqLen(n.List) == 0 { break OpSwitch } 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 { if n.Left != nil { return true } - if n.List == nil { + if nodeSeqLen(n.List) == 0 { p := fmt.Sprintf(f, args...) Yyerror("missing argument to %s: %v", p, n) return false } - if n.List.Next != nil { + if nodeSeqLen(n.List) > 1 { p := fmt.Sprintf(f, args...) Yyerror("too many arguments to %s: %v", p, n) - n.Left = n.List.N - n.List = nil + n.Left = nodeSeqFirst(n.List) + setNodeSeq(&n.List, nil) return false } - n.Left = n.List.N - n.List = nil + n.Left = nodeSeqFirst(n.List) + setNodeSeq(&n.List, nil) return true } @@ -2355,26 +2356,26 @@ func twoarg(n *Node) bool { if n.Left != nil { return true } - if n.List == nil { + if nodeSeqLen(n.List) == 0 { Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), n) return false } - n.Left = n.List.N - if n.List.Next == nil { + n.Left = nodeSeqFirst(n.List) + if nodeSeqLen(n.List) == 1 { Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), n) - n.List = nil + setNodeSeq(&n.List, nil) 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) - n.List = nil + setNodeSeq(&n.List, nil) return false } - n.Right = n.List.Next.N - n.List = nil + n.Right = nodeSeqSecond(n.List) + setNodeSeq(&n.List, nil) return true } @@ -2915,8 +2916,8 @@ func typecheckcomplit(np **Node) { }() if n.Right == nil { - if n.List != nil { - setlineno(n.List.N) + if nodeSeqLen(n.List) != 0 { + setlineno(nodeSeqFirst(n.List)) } Yyerror("missing type in composite literal") n.Type = nil @@ -2966,22 +2967,22 @@ func typecheckcomplit(np **Node) { case TARRAY: // Only allocate hash if there are some key/value pairs. var hash map[int64]*Node - for ll := n.List; ll != nil; ll = ll.Next { - if ll.N.Op == OKEY { + for it := nodeSeqIterate(n.List); !it.Done(); it.Next() { + if it.N().Op == OKEY { hash = make(map[int64]*Node) break } } length := int64(0) i := 0 - for ll := n.List; ll != nil; ll = ll.Next { - l := ll.N + for it := nodeSeqIterate(n.List); !it.Done(); it.Next() { + l := it.N() setlineno(l) if l.Op != OKEY { l = Nod(OKEY, Nodintconst(int64(i)), l) l.Left.Type = Types[TINT] l.Left.Typecheck = 1 - ll.N = l + *it.P() = l } typecheck(&l.Left, Erv) @@ -3024,11 +3025,11 @@ func typecheckcomplit(np **Node) { case TMAP: hash := make(map[uint32][]*Node) var l *Node - for ll := n.List; ll != nil; ll = ll.Next { - l = ll.N + for it := nodeSeqIterate(n.List); !it.Done(); it.Next() { + l = it.N() setlineno(l) if l.Op != OKEY { - typecheck(&ll.N, Erv) + typecheck(it.P(), Erv) Yyerror("missing key in map literal") continue } @@ -3053,14 +3054,14 @@ func typecheckcomplit(np **Node) { case TSTRUCT: bad := 0 - if n.List != nil && nokeys(n.List) { + if nodeSeqLen(n.List) != 0 && nokeys(n.List) { // simple list of variables f := t.Type var s *Sym - for ll := n.List; ll != nil; ll = ll.Next { - setlineno(ll.N) - typecheck(&ll.N, Erv) + for it := nodeSeqIterate(n.List); !it.Done(); it.Next() { + setlineno(it.N()) + typecheck(it.P(), Erv) if f == nil { if bad == 0 { Yyerror("too many values in struct initializer") @@ -3075,11 +3076,11 @@ func typecheckcomplit(np **Node) { } // 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) - ll.N.Left.Type = f - ll.N.Left.Typecheck = 1 + *it.P() = Nod(OKEY, newname(f.Sym), it.N()) + it.N().Left.Type = f + it.N().Left.Typecheck = 1 f = f.Down } @@ -3094,15 +3095,15 @@ func typecheckcomplit(np **Node) { var f *Type var l *Node var s1 *Sym - for ll := n.List; ll != nil; ll = ll.Next { - l = ll.N + for it := nodeSeqIterate(n.List); !it.Done(); it.Next() { + l = it.N() setlineno(l) if l.Op != OKEY { if bad == 0 { Yyerror("mixture of field:value and value initializers") } bad++ - typecheck(&ll.N, Erv) + typecheck(it.P(), Erv) continue } @@ -3313,19 +3314,20 @@ func checkassignto(src *Type, dst *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. - 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 { - typecheck(&ll.N, Erv|Easgn) + if it.N().Name == nil || it.N().Name.Defn != n || it.N().Name.Param.Ntype != nil { + typecheck(it.P(), Erv|Easgn) } } - cl := count(n.List) - cr := count(n.Rlist) + cl := nodeSeqLen(n.List) + cr := nodeSeqLen(n.Rlist) if cl > 1 && cr == 1 { - typecheck(&n.Rlist.N, Erv|Efnstruct) + it := nodeSeqIterate(n.Rlist) + typecheck(it.P(), Erv|Efnstruct) } else { typechecklist(n.Rlist, Erv) } @@ -3335,23 +3337,24 @@ func typecheckas2(n *Node) { var r *Node if cl == cr { // easy - ll := n.List - lr := n.Rlist - for ; ll != nil; ll, lr = ll.Next, lr.Next { - if ll.N.Type != nil && lr.N.Type != nil { - lr.N = assignconv(lr.N, ll.N.Type, "assignment") + llit := nodeSeqIterate(n.List) + lrit := nodeSeqIterate(n.Rlist) + for llit = nodeSeqIterate(n.List); !llit.Done(); llit.Next() { + if llit.N().Type != nil && lrit.N().Type != nil { + *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 { - defaultlit(&lr.N, nil) - ll.N.Type = lr.N.Type + if llit.N().Name != nil && llit.N().Name.Defn == n && llit.N().Name.Param.Ntype == nil { + defaultlit(lrit.P(), nil) + llit.N().Type = lrit.N().Type } + lrit.Next() } goto out } - l = n.List.N - r = n.Rlist.N + l = nodeSeqFirst(n.List) + r = nodeSeqFirst(n.Rlist) // x,y,z = f() if cr == 1 { @@ -3370,12 +3373,12 @@ func typecheckas2(n *Node) { n.Op = OAS2FUNC var s Iter t := Structfirst(&s, &r.Type) - for ll := n.List; ll != nil; ll = ll.Next { - if t.Type != nil && ll.N.Type != nil { - checkassignto(t.Type, ll.N) + for it := nodeSeqIterate(n.List); !it.Done(); it.Next() { + if t.Type != nil && it.N().Type != nil { + checkassignto(t.Type, it.N()) } - if ll.N.Name != nil && ll.N.Name.Defn == n && ll.N.Name.Param.Ntype == nil { - ll.N.Type = t.Type + if it.N().Name != nil && it.N().Name.Defn == n && it.N().Name.Param.Ntype == nil { + it.N().Type = t.Type } t = structnext(&s) } @@ -3409,7 +3412,7 @@ func typecheckas2(n *Node) { if l.Name != nil && l.Name.Defn == n { l.Type = r.Type } - l := n.List.Next.N + l := nodeSeqSecond(n.List) if l.Type != nil && l.Type.Etype != TBOOL { checkassignto(Types[TBOOL], l) } @@ -3427,9 +3430,9 @@ mismatch: out: n.Typecheck = 1 - for ll := n.List; ll != nil; ll = ll.Next { - if ll.N.Typecheck == 0 { - typecheck(&ll.N, Erv|Easgn) + for it := nodeSeqIterate(n.List); !it.Done(); it.Next() { + if it.N().Typecheck == 0 { + typecheck(it.P(), Erv|Easgn) } } } @@ -3462,23 +3465,23 @@ func stringtoarraylit(np **Node) { } s := n.Left.Val().U.(string) - var l *NodeList + var l []*Node if n.Type.Type.Etype == TUINT8 { // []byte 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 { // []rune i := 0 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++ } } nn := Nod(OCOMPLIT, nil, typenod(n.Type)) - nn.List = l + setNodeSeq(&nn.List, l) typecheck(&nn, Erv) *np = nn } @@ -3880,43 +3883,16 @@ func markbreak(n *Node, implicit *Node) { markbreak(n.Right, implicit) markbreaklist(n.Ninit, implicit) - markbreakslice(n.Nbody.Slice(), implicit) + markbreaklist(n.Nbody, implicit) markbreaklist(n.List, implicit) markbreaklist(n.Rlist, implicit) } } -func markbreaklist(l *NodeList, implicit *Node) { - var n *Node - var lab *Label - - 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] { +func markbreaklist(l nodesOrNodeList, implicit *Node) { + for it := nodeSeqIterate(l); !it.Done(); it.Next() { + n := it.N() + if n.Op == OLABEL && it.Len() > 1 && n.Name.Defn == nodeSeqSlice(it.Seq())[1] { switch n.Name.Defn.Op { case OFOR, OSWITCH, OTYPESW, OSELECT, ORANGE: lab := new(Label) @@ -3924,7 +3900,7 @@ func markbreakslice(l []*Node, implicit *Node) { n.Left.Sym.Label = lab markbreak(n.Name.Defn, n.Name.Defn) n.Left.Sym.Label = nil - i++ + it.Next() continue } } @@ -3991,11 +3967,11 @@ func (n *Node) isterminating() bool { return false } def := 0 - for l := n.List; l != nil; l = l.Next { - if !l.N.Nbody.isterminating() { + for it := nodeSeqIterate(n.List); !it.Done(); it.Next() { + if !it.N().Nbody.isterminating() { return false } - if l.N.List == nil { // default + if nodeSeqLen(it.N().List) == 0 { // default def = 1 } } @@ -4011,7 +3987,7 @@ func (n *Node) isterminating() bool { func checkreturn(fn *Node) { if fn.Type.Outtuple != 0 && len(fn.Nbody.Slice()) != 0 { - markbreakslice(fn.Nbody.Slice(), nil) + markbreaklist(fn.Nbody, nil) if !fn.Nbody.isterminating() { yyerrorl(fn.Func.Endlineno, "missing return at end of function") } -- 2.48.1