mirror of
https://github.com/golang/go
synced 2024-11-12 05:30:21 -07:00
cmd/compile: simplify Iter
Passes toolstash -cmp. Change-Id: I325b02dcc8412ded0dc304d43377c0bdf59c66a8 Reviewed-on: https://go-review.googlesource.com/20405 Reviewed-by: David Crawshaw <crawshaw@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
5011431295
commit
7758a9405f
@ -295,9 +295,9 @@ func dowidth(t *Type) {
|
||||
case TFUNCARGS:
|
||||
t1 := t.Type
|
||||
|
||||
w = widstruct(t.Type, *getthis(t1), 0, 0)
|
||||
w = widstruct(t.Type, *getinarg(t1), w, Widthreg)
|
||||
w = widstruct(t.Type, *Getoutarg(t1), w, Widthreg)
|
||||
w = widstruct(t.Type, getthisx(t1), 0, 0)
|
||||
w = widstruct(t.Type, getinargx(t1), w, Widthreg)
|
||||
w = widstruct(t.Type, getoutargx(t1), w, Widthreg)
|
||||
t1.Argwid = w
|
||||
if w%int64(Widthreg) != 0 {
|
||||
Warn("bad type %v %d\n", t1, w)
|
||||
@ -616,27 +616,18 @@ func typeinit() {
|
||||
|
||||
// compute total size of f's in/out arguments.
|
||||
func Argsize(t *Type) int {
|
||||
var save Iter
|
||||
var x int64
|
||||
var w int64
|
||||
|
||||
w := int64(0)
|
||||
|
||||
fp := Structfirst(&save, Getoutarg(t))
|
||||
for fp != nil {
|
||||
x = fp.Width + fp.Type.Width
|
||||
if x > w {
|
||||
for fp, ip := IterFields(getoutargx(t)); fp != nil; fp = ip.Next() {
|
||||
if x := fp.Width + fp.Type.Width; x > w {
|
||||
w = x
|
||||
}
|
||||
fp = structnext(&save)
|
||||
}
|
||||
|
||||
fp = funcfirst(&save, t)
|
||||
for fp != nil {
|
||||
x = fp.Width + fp.Type.Width
|
||||
if x > w {
|
||||
for fp, ip := IterParams(t); fp != nil; fp = ip.Next() {
|
||||
if x := fp.Width + fp.Type.Width; x > w {
|
||||
w = x
|
||||
}
|
||||
fp = funcnext(&save)
|
||||
}
|
||||
|
||||
w = (w + int64(Widthptr) - 1) &^ (int64(Widthptr) - 1)
|
||||
|
@ -1677,8 +1677,7 @@ func Igen(n *Node, a *Node, res *Node) {
|
||||
cgen_callinter(n, nil, 0)
|
||||
}
|
||||
|
||||
var flist Iter
|
||||
fp := Structfirst(&flist, Getoutarg(n.Left.Type))
|
||||
fp, _ := IterFields(getoutargx(n.Left.Type))
|
||||
*a = Node{}
|
||||
a.Op = OINDREG
|
||||
a.Reg = int16(Thearch.REGSP)
|
||||
@ -2226,8 +2225,7 @@ func stkof(n *Node) int64 {
|
||||
t = t.Type
|
||||
}
|
||||
|
||||
var flist Iter
|
||||
t = Structfirst(&flist, Getoutarg(t))
|
||||
t, _ = IterFields(getoutargx(t))
|
||||
if t != nil {
|
||||
return t.Width + Ctxt.FixedFrameSize()
|
||||
}
|
||||
@ -2563,8 +2561,7 @@ func cgen_callret(n *Node, res *Node) {
|
||||
t = t.Type
|
||||
}
|
||||
|
||||
var flist Iter
|
||||
fp := Structfirst(&flist, Getoutarg(t))
|
||||
fp, _ := IterFields(getoutargx(t))
|
||||
if fp == nil {
|
||||
Fatalf("cgen_callret: nil")
|
||||
}
|
||||
@ -2588,8 +2585,7 @@ func cgen_aret(n *Node, res *Node) {
|
||||
t = t.Type
|
||||
}
|
||||
|
||||
var flist Iter
|
||||
fp := Structfirst(&flist, Getoutarg(t))
|
||||
fp, _ := IterFields(getoutargx(t))
|
||||
if fp == nil {
|
||||
Fatalf("cgen_aret: nil")
|
||||
}
|
||||
|
@ -548,8 +548,7 @@ func nodarg(t *Type, fp int) *Node {
|
||||
n = Nod(ONAME, nil, nil)
|
||||
n.Sym = Lookup(".args")
|
||||
n.Type = t
|
||||
var savet Iter
|
||||
first := Structfirst(&savet, &t)
|
||||
first, _ := IterFields(t)
|
||||
if first == nil {
|
||||
Fatalf("nodarg: bad struct")
|
||||
}
|
||||
|
@ -338,8 +338,7 @@ func copyret(n *Node, order *Order) Nodes {
|
||||
|
||||
var l1 []*Node
|
||||
var l2 []*Node
|
||||
var tl Iter
|
||||
for t := Structfirst(&tl, &n.Type); t != nil; t = structnext(&tl) {
|
||||
for t, it := IterFields(n.Type); t != nil; t = it.Next() {
|
||||
tmp := temp(t.Type)
|
||||
l1 = append(l1, tmp)
|
||||
l2 = append(l2, tmp)
|
||||
|
@ -377,8 +377,7 @@ func compile(fn *Node) {
|
||||
|
||||
if Curfn.Type.Outnamed {
|
||||
// add clearing of the output parameters
|
||||
var save Iter
|
||||
for t := Structfirst(&save, Getoutarg(Curfn.Type)); t != nil; t = structnext(&save) {
|
||||
for t, it := IterFields(getoutargx(Curfn.Type)); t != nil; t = it.Next() {
|
||||
if t.Nname != nil {
|
||||
n := Nod(OAS, t.Nname, nil)
|
||||
typecheck(&n, Etop)
|
||||
|
@ -2407,8 +2407,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
|
||||
|
||||
// Start exit block, find address of result.
|
||||
s.startBlock(bNext)
|
||||
var titer Iter
|
||||
fp := Structfirst(&titer, Getoutarg(n.Left.Type))
|
||||
fp, _ := IterFields(getoutargx(n.Left.Type))
|
||||
if fp == nil || k != callNormal {
|
||||
// call has no return value. Continue with the next statement.
|
||||
return nil
|
||||
|
@ -1892,14 +1892,13 @@ func expandmeth(t *Type) {
|
||||
|
||||
// Given funarg struct list, return list of ODCLFIELD Node fn args.
|
||||
func structargs(tl **Type, mustname int) []*Node {
|
||||
var savet Iter
|
||||
var a *Node
|
||||
var n *Node
|
||||
var buf string
|
||||
|
||||
var args []*Node
|
||||
gen := 0
|
||||
for t := Structfirst(&savet, tl); t != nil; t = structnext(&savet) {
|
||||
for t, it := IterFields(*tl); t != nil; t = it.Next() {
|
||||
n = nil
|
||||
if mustname != 0 && (t.Sym == nil || t.Sym.Name == "_") {
|
||||
// invent a name so that we can refer to it in the trampoline
|
||||
@ -2250,10 +2249,8 @@ func liststmt(l []*Node) *Node {
|
||||
|
||||
// return nelem of list
|
||||
func structcount(t *Type) int {
|
||||
var s Iter
|
||||
|
||||
v := 0
|
||||
for t = Structfirst(&s, &t); t != nil; t = structnext(&s) {
|
||||
for t, it := IterFields(t); t != nil; t = it.Next() {
|
||||
v++
|
||||
}
|
||||
return v
|
||||
|
@ -164,101 +164,48 @@ type Type struct {
|
||||
Lastfn *Node // for usefield
|
||||
}
|
||||
|
||||
// Iter provides an abstraction for iterating across struct fields
|
||||
// and function parameters.
|
||||
// Iter provides an abstraction for iterating across struct fields,
|
||||
// interface methods, and function parameters.
|
||||
type Iter struct {
|
||||
Done int
|
||||
Tfunc *Type
|
||||
T *Type
|
||||
a, b *Type
|
||||
}
|
||||
|
||||
// iterator to walk a structure declaration
|
||||
func Structfirst(s *Iter, nn **Type) *Type {
|
||||
var t *Type
|
||||
|
||||
n := *nn
|
||||
if n == nil {
|
||||
goto bad
|
||||
// IterFields returns the first field or method in struct or interface type t
|
||||
// and an Iter value to continue iterating across the rest.
|
||||
func IterFields(t *Type) (*Type, Iter) {
|
||||
if t.Etype != TSTRUCT && t.Etype != TINTER {
|
||||
Fatalf("IterFields: type %v does not have fields", t)
|
||||
}
|
||||
|
||||
switch n.Etype {
|
||||
default:
|
||||
goto bad
|
||||
|
||||
case TSTRUCT, TINTER, TFUNC:
|
||||
break
|
||||
}
|
||||
|
||||
t = n.Type
|
||||
if t == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if t.Etype != TFIELD {
|
||||
Fatalf("structfirst: not field %v", t)
|
||||
}
|
||||
|
||||
s.T = t
|
||||
return t
|
||||
|
||||
bad:
|
||||
Fatalf("structfirst: not struct %v", n)
|
||||
|
||||
return nil
|
||||
i := Iter{a: t.Type}
|
||||
f := i.Next()
|
||||
return f, i
|
||||
}
|
||||
|
||||
func structnext(s *Iter) *Type {
|
||||
n := s.T
|
||||
t := n.Down
|
||||
if t == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if t.Etype != TFIELD {
|
||||
Fatalf("structnext: not struct %v", n)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
s.T = t
|
||||
return t
|
||||
}
|
||||
|
||||
// iterator to this and inargs in a function
|
||||
func funcfirst(s *Iter, t *Type) *Type {
|
||||
var fp *Type
|
||||
|
||||
if t == nil {
|
||||
goto bad
|
||||
}
|
||||
|
||||
// IterParams returns the first reeiver or input parameter in function type t
|
||||
// and an Iter value to continue iterating across the rest.
|
||||
func IterParams(t *Type) (*Type, Iter) {
|
||||
if t.Etype != TFUNC {
|
||||
goto bad
|
||||
Fatalf("IterParams: type %v does not have params", t)
|
||||
}
|
||||
|
||||
s.Tfunc = t
|
||||
s.Done = 0
|
||||
fp = Structfirst(s, getthis(t))
|
||||
if fp == nil {
|
||||
s.Done = 1
|
||||
fp = Structfirst(s, getinarg(t))
|
||||
}
|
||||
|
||||
return fp
|
||||
|
||||
bad:
|
||||
Fatalf("funcfirst: not func %v", t)
|
||||
return nil
|
||||
i := Iter{a: getthisx(t).Type, b: getinargx(t).Type}
|
||||
f := i.Next()
|
||||
return f, i
|
||||
}
|
||||
|
||||
func funcnext(s *Iter) *Type {
|
||||
fp := structnext(s)
|
||||
if fp == nil && s.Done == 0 {
|
||||
s.Done = 1
|
||||
fp = Structfirst(s, getinarg(s.Tfunc))
|
||||
// Next returns the next field, method, or parameter, if any.
|
||||
func (i *Iter) Next() *Type {
|
||||
if i.a == nil {
|
||||
if i.b == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fp
|
||||
i.a, i.b = i.b, nil
|
||||
}
|
||||
t := i.a
|
||||
if t.Etype != TFIELD {
|
||||
Fatalf("Iter.Next: type %v is not a field", t)
|
||||
}
|
||||
i.a = t.Down
|
||||
return t
|
||||
}
|
||||
|
||||
func getthis(t *Type) **Type {
|
||||
|
@ -3371,8 +3371,7 @@ func typecheckas2(n *Node) {
|
||||
goto mismatch
|
||||
}
|
||||
n.Op = OAS2FUNC
|
||||
var s Iter
|
||||
t := Structfirst(&s, &r.Type)
|
||||
t, s := IterFields(r.Type)
|
||||
for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
|
||||
if t.Type != nil && it.N().Type != nil {
|
||||
checkassignto(t.Type, it.N())
|
||||
@ -3380,7 +3379,7 @@ func typecheckas2(n *Node) {
|
||||
if it.N().Name != nil && it.N().Name.Defn == n && it.N().Name.Param.Ntype == nil {
|
||||
it.N().Type = t.Type
|
||||
}
|
||||
t = structnext(&s)
|
||||
t = s.Next()
|
||||
}
|
||||
|
||||
goto out
|
||||
|
@ -1706,12 +1706,11 @@ func ascompatet(op Op, nl Nodes, nr **Type, fp int, init *Nodes) []*Node {
|
||||
var l *Node
|
||||
var tmp *Node
|
||||
var a *Node
|
||||
var saver Iter
|
||||
|
||||
// check assign type list to
|
||||
// a expression list. called in
|
||||
// expr-list = func()
|
||||
r := Structfirst(&saver, nr)
|
||||
r, saver := IterFields(*nr)
|
||||
|
||||
var nn []*Node
|
||||
var mm []*Node
|
||||
@ -1723,7 +1722,7 @@ func ascompatet(op Op, nl Nodes, nr **Type, fp int, init *Nodes) []*Node {
|
||||
}
|
||||
l = it.N()
|
||||
if isblank(l) {
|
||||
r = structnext(&saver)
|
||||
r = saver.Next()
|
||||
continue
|
||||
}
|
||||
|
||||
@ -1748,7 +1747,7 @@ func ascompatet(op Op, nl Nodes, nr **Type, fp int, init *Nodes) []*Node {
|
||||
}
|
||||
|
||||
nn = append(nn, a)
|
||||
r = structnext(&saver)
|
||||
r = saver.Next()
|
||||
}
|
||||
|
||||
if !it.Done() || r != nil {
|
||||
@ -1797,12 +1796,10 @@ func mkdotargslice(lr0, nn []*Node, l *Type, fp int, init *Nodes, ddd *Node) []*
|
||||
|
||||
// helpers for shape errors
|
||||
func dumptypes(nl **Type, what string) string {
|
||||
var savel Iter
|
||||
|
||||
fmt_ := ""
|
||||
fmt_ += "\t"
|
||||
first := 1
|
||||
for l := Structfirst(&savel, nl); l != nil; l = structnext(&savel) {
|
||||
for l, it := IterFields(*nl); l != nil; l = it.Next() {
|
||||
if first != 0 {
|
||||
first = 0
|
||||
} else {
|
||||
@ -1844,10 +1841,8 @@ func dumpnodetypes(l []*Node, what string) string {
|
||||
// return expr-list
|
||||
// func(expr-list)
|
||||
func ascompatte(op Op, call *Node, isddd bool, nl **Type, lr []*Node, fp int, init *Nodes) []*Node {
|
||||
var savel Iter
|
||||
|
||||
lr0 := lr
|
||||
l := Structfirst(&savel, nl)
|
||||
l, savel := IterFields(*nl)
|
||||
var r *Node
|
||||
if nodeSeqLen(lr) > 0 {
|
||||
r = nodeSeqFirst(lr)
|
||||
@ -1873,7 +1868,7 @@ func ascompatte(op Op, call *Node, isddd bool, nl **Type, lr []*Node, fp int, in
|
||||
// copy into temporaries.
|
||||
var alist []*Node
|
||||
|
||||
for l := Structfirst(&savel, &r.Type); l != nil; l = structnext(&savel) {
|
||||
for l, it := IterFields(r.Type); l != nil; l = it.Next() {
|
||||
a = temp(l.Type)
|
||||
alist = append(alist, a)
|
||||
}
|
||||
@ -1886,13 +1881,13 @@ func ascompatte(op Op, call *Node, isddd bool, nl **Type, lr []*Node, fp int, in
|
||||
init.Append(a)
|
||||
lr = alist
|
||||
r = nodeSeqFirst(lr)
|
||||
l = Structfirst(&savel, nl)
|
||||
l, savel = IterFields(*nl)
|
||||
}
|
||||
|
||||
loop:
|
||||
if l != nil && l.Isddd {
|
||||
// the ddd parameter must be last
|
||||
ll = structnext(&savel)
|
||||
ll = savel.Next()
|
||||
|
||||
if ll != nil {
|
||||
Yyerror("... must be last argument")
|
||||
@ -1935,7 +1930,7 @@ loop:
|
||||
a = convas(a, init)
|
||||
nn = append(nn, a)
|
||||
|
||||
l = structnext(&savel)
|
||||
l = savel.Next()
|
||||
r = nil
|
||||
lr = lr[1:]
|
||||
if len(lr) > 0 {
|
||||
@ -2036,7 +2031,7 @@ func walkprint(nn *Node, init *Nodes) *Node {
|
||||
continue
|
||||
}
|
||||
|
||||
t = *getinarg(on.Type)
|
||||
t = getinargx(on.Type)
|
||||
if t != nil {
|
||||
t = t.Type
|
||||
}
|
||||
@ -2590,12 +2585,11 @@ func vmatch1(l *Node, r *Node) bool {
|
||||
// generate and return code to allocate
|
||||
// copies of escaped parameters to the heap.
|
||||
func paramstoheap(argin **Type, out int) []*Node {
|
||||
var savet Iter
|
||||
var v *Node
|
||||
var as *Node
|
||||
|
||||
var nn []*Node
|
||||
for t := Structfirst(&savet, argin); t != nil; t = structnext(&savet) {
|
||||
for t, it := IterFields(*argin); t != nil; t = it.Next() {
|
||||
v = t.Nname
|
||||
if v != nil && v.Sym != nil && v.Sym.Name[0] == '~' && v.Sym.Name[1] == 'r' { // unnamed result
|
||||
v = nil
|
||||
@ -2636,11 +2630,10 @@ func paramstoheap(argin **Type, out int) []*Node {
|
||||
|
||||
// walk through argout parameters copying back to stack
|
||||
func returnsfromheap(argin **Type) []*Node {
|
||||
var savet Iter
|
||||
var v *Node
|
||||
|
||||
var nn []*Node
|
||||
for t := Structfirst(&savet, argin); t != nil; t = structnext(&savet) {
|
||||
for t, it := IterFields(*argin); t != nil; t = it.Next() {
|
||||
v = t.Nname
|
||||
if v == nil || v.Class != PHEAP|PPARAMOUT {
|
||||
continue
|
||||
|
Loading…
Reference in New Issue
Block a user