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 <crawshaw@golang.org>
diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go
index 4f3d3dd..9870614 100644
--- a/src/cmd/compile/internal/gc/swt.go
+++ b/src/cmd/compile/internal/gc/swt.go
@@ -105,11 +105,10 @@
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 @@
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 @@
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 @@
}
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 @@
// 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 @@
}
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 @@
// 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 @@
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 @@
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 @@
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 @@
// 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 @@
sw.Left = nil
if cond == nil {
- sw.List = nil
+ setNodeSeq(&sw.List, nil)
return
}
if cond.Right == nil {
@@ -552,7 +552,7 @@
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 @@
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 @@
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) 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 @@
}
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 @@
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
}