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>
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)
// compute total size of f's in/out arguments.
func Argsize(t *Type) int {
- var save Iter
- var x int64
-
- w := int64(0)
+ var w int64
- 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)
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)
t = t.Type
}
- var flist Iter
- t = Structfirst(&flist, Getoutarg(t))
+ t, _ = IterFields(getoutargx(t))
if t != nil {
return t.Width + Ctxt.FixedFrameSize()
}
t = t.Type
}
- var flist Iter
- fp := Structfirst(&flist, Getoutarg(t))
+ fp, _ := IterFields(getoutargx(t))
if fp == nil {
Fatalf("cgen_callret: nil")
}
t = t.Type
}
- var flist Iter
- fp := Structfirst(&flist, Getoutarg(t))
+ fp, _ := IterFields(getoutargx(t))
if fp == nil {
Fatalf("cgen_aret: nil")
}
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")
}
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)
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)
// 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
// 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
// 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
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
- }
-
- switch n.Etype {
- default:
- goto bad
-
- case TSTRUCT, TINTER, TFUNC:
- break
- }
-
- t = n.Type
- if t == nil {
- return nil
+// 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)
}
+ i := Iter{a: t.Type}
+ f := i.Next()
+ return f, i
+}
- if t.Etype != TFIELD {
- Fatalf("structfirst: not field %v", t)
+// 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 {
+ Fatalf("IterParams: type %v does not have params", t)
}
-
- s.T = t
- return t
-
-bad:
- Fatalf("structfirst: not struct %v", n)
-
- return nil
+ i := Iter{a: getthisx(t).Type, b: getinargx(t).Type}
+ f := i.Next()
+ return f, i
}
-func structnext(s *Iter) *Type {
- n := s.T
- t := n.Down
- if t == nil {
- return nil
+// 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
+ }
+ i.a, i.b = i.b, nil
}
-
+ t := i.a
if t.Etype != TFIELD {
- Fatalf("structnext: not struct %v", n)
-
- return nil
+ Fatalf("Iter.Next: type %v is not a field", t)
}
-
- s.T = t
+ i.a = t.Down
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
- }
-
- if t.Etype != TFUNC {
- goto bad
- }
-
- 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
-}
-
-func funcnext(s *Iter) *Type {
- fp := structnext(s)
- if fp == nil && s.Done == 0 {
- s.Done = 1
- fp = Structfirst(s, getinarg(s.Tfunc))
- }
-
- return fp
-}
-
func getthis(t *Type) **Type {
if t.Etype != TFUNC {
Fatalf("getthis: not a func %v", t)
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())
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
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
}
l = it.N()
if isblank(l) {
- r = structnext(&saver)
+ r = saver.Next()
continue
}
}
nn = append(nn, a)
- r = structnext(&saver)
+ r = saver.Next()
}
if !it.Done() || r != nil {
// 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 {
// 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)
// 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)
}
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")
a = convas(a, init)
nn = append(nn, a)
- l = structnext(&savel)
+ l = savel.Next()
r = nil
lr = lr[1:]
if len(lr) > 0 {
continue
}
- t = *getinarg(on.Type)
+ t = getinargx(on.Type)
if t != nil {
t = t.Type
}
// 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
// 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