}
ret := AMEM
- for f := t.Type; f != nil; f = f.Down {
+ for f, it := IterFields(t); f != nil; f = it.Next() {
// All fields must be comparable.
a := algtype1(f.Type, bad)
if a == ANOEQ {
func offmod(t *Type) {
o := int32(0)
- for f := t.Type; f != nil; f = f.Down {
+ for f, it := IterFields(t); f != nil; f = it.Next() {
if f.Etype != TFIELD {
Fatalf("offmod: not TFIELD: %v", Tconv(f, obj.FmtLong))
}
}
lastzero := int64(0)
var w int64
- for f := t.Type; f != nil; f = f.Down {
+ for f, it := IterFields(t); f != nil; f = it.Next() {
if f.Etype != TFIELD {
Fatalf("widstruct: not TFIELD: %v", Tconv(f, obj.FmtLong))
}
// TODO(gri) Determine if they are already sorted
// in which case we can drop this step.
var methods []*Type
- for m := t.Method; m != nil; m = m.Down {
+ for m, it := IterMethods(t); m != nil; m = it.Next() {
methods = append(methods, m)
}
sort.Sort(methodbyname(methods))
}
p.int(countfield(t))
- for f := t.Type; f != nil; f = f.Down {
+ for f, it := IterFields(t); f != nil; f = it.Next() {
p.field(f)
if p.trace && f.Down != nil {
p.tracef("\n")
}
p.int(countfield(t))
- for m := t.Type; m != nil; m = m.Down {
+ for m, it := IterFields(t); m != nil; m = it.Next() {
p.method(m)
if p.trace && m.Down != nil {
p.tracef("\n")
n = -n
}
p.int(n)
- for q := params.Type; q != nil; q = q.Down {
+ for q, it := IterFields(params); q != nil; q = it.Next() {
p.param(q, n)
}
}
tp = &f.Down
}
- for f := t.Type; f != nil && !t.Broke; f = f.Down {
+ for f, it := IterFields(t); f != nil && !t.Broke; f = it.Next() {
if f.Broke {
t.Broke = true
}
tp = &f.Down
}
- for f := t.Type; f != nil && !t.Broke; f = f.Down {
+ for f, it := IterFields(t); f != nil && !t.Broke; f = it.Next() {
if f.Broke {
t.Broke = true
}
if n.Left == nil && f.Type.Etype == TINTER {
// embedded interface, inline methods
- for t1 := f.Type.Type; t1 != nil; t1 = t1.Down {
+ for t1, it := IterFields(f.Type); t1 != nil; t1 = it.Next() {
f = typ(TFIELD)
f.Type = t1.Type
f.Broke = t1.Broke
}
}
- for f := t.Type; f != nil && !t.Broke; f = f.Down {
+ for f, it := IterFields(t); f != nil && !t.Broke; f = it.Next() {
if f.Broke {
t.Broke = true
}
}
if pa.Etype == TSTRUCT {
- for f := pa.Type; f != nil; f = f.Down {
+ for f, it := IterFields(pa); f != nil; f = it.Next() {
if f.Sym == sf {
Yyerror("type %v has both field and method named %v", pa, sf)
return
n.Type = t
var d *Type // last found
- for f := pa.Method; f != nil; f = f.Down {
+ for f, it := IterMethods(pa); f != nil; f = it.Next() {
d = f
if f.Etype != TFIELD {
Fatalf("addmethod: not TFIELD: %v", Tconv(f, obj.FmtLong))
}
var m []*Type
- for f := t.Method; f != nil; f = f.Down {
+ for f, it := IterMethods(t); f != nil; f = it.Next() {
dumpexporttype(f)
m = append(m, f)
}
break
}
fmt.Fprintf(b, "#define %s__size %d\n", t.Sym.Name, int(t.Width))
- for t = t.Type; t != nil; t = t.Down {
+ for t, it := IterFields(t); t != nil; t = it.Next() {
if !isblanksym(t.Sym) {
fmt.Fprintf(b, "#define %s_%s %d\n", n.Sym.Name, t.Sym.Name, int(t.Width))
}
case TINTER:
var buf bytes.Buffer
buf.WriteString("interface {")
- for t1 := t.Type; t1 != nil; t1 = t1.Down {
+ for t1, it := IterFields(t); t1 != nil; t1 = it.Next() {
buf.WriteString(" ")
switch {
case t1.Sym == nil:
if t.Funarg {
buf.WriteString("(")
if fmtmode == FTypeId || fmtmode == FErr { // no argument names on function signature, and no "noescape"/"nosplit" tags
- for t1 := t.Type; t1 != nil; t1 = t1.Down {
+ for t1, it := IterFields(t); t1 != nil; t1 = it.Next() {
buf.WriteString(Tconv(t1, obj.FmtShort))
if t1.Down != nil {
buf.WriteString(", ")
}
}
} else {
- for t1 := t.Type; t1 != nil; t1 = t1.Down {
+ for t1, it := IterFields(t); t1 != nil; t1 = it.Next() {
buf.WriteString(Tconv(t1, 0))
if t1.Down != nil {
buf.WriteString(", ")
buf.WriteString(")")
} else {
buf.WriteString("struct {")
- for t1 := t.Type; t1 != nil; t1 = t1.Down {
+ for t1, it := IterFields(t); t1 != nil; t1 = it.Next() {
buf.WriteString(" ")
buf.WriteString(Tconv(t1, obj.FmtLong))
if t1.Down != nil {
Fatalf("struct not at offset 0")
}
- for field := t.Type; field != nil; field = field.Down {
+ for field, it := IterFields(t); field != nil; field = it.Next() {
if field.Etype != TFIELD {
Fatalf("bad struct")
}
case TSTRUCT:
o := int64(0)
var fieldoffset int64
- for t1 := t.Type; t1 != nil; t1 = t1.Down {
+ for t1, it := IterFields(t); t1 != nil; t1 = it.Next() {
fieldoffset = t1.Width
*xoffset += fieldoffset - o
onebitwalktype1(t1.Type, xoffset, bv)
// make list of methods for t,
// generating code if necessary.
var ms []*Sig
- for f := mt.Xmethod; f != nil; f = f.Down {
+ for f, it2 := IterAllMethods(mt); f != nil; f = it2.Next() {
if f.Etype != TFIELD {
Fatalf("methods: not field %v", f)
}
if countfield(t) > ssa.MaxStruct {
return false
}
- for t1 := t.Type; t1 != nil; t1 = t1.Down {
+ for t1, it := IterFields(t); t1 != nil; t1 = it.Next() {
if !canSSAType(t1.Type) {
return false
}
}
var i int64
- for t1 := t.Type; t1 != nil; t1 = t1.Down {
+ for t1, it := IterFields(t); t1 != nil; t1 = it.Next() {
if t1.Etype != TFIELD {
panic("non-TFIELD in TSTRUCT")
}
substAny(t.ResultsP(), types)
case TSTRUCT:
- for t = t.Type; t != nil; t = t.Down {
+ for t, it := IterFields(t); t != nil; t = it.Next() {
substAny(&t.Type, types)
}
}
nt.Type = t.Type.Copy()
xt := nt.Type
- for t = t.Type; t != nil; t = t.Down {
+ for t, it := IterFields(t); t != nil; t = it.Next() {
xt.Type = deep(t.Type)
xt.Down = t.Down.Copy()
xt = xt.Down
c := 0
if u.Etype == TSTRUCT || u.Etype == TINTER {
- for f := u.Type; f != nil; f = f.Down {
+ for f, it := IterFields(u); f != nil; f = it.Next() {
if f.Sym == s || (ignorecase && f.Type.Etype == TFUNC && f.Type.Thistuple > 0 && strings.EqualFold(f.Sym.Name, s.Name)) {
if save != nil {
*save = f
u = methtype(t, 0)
if u != nil {
- for f := u.Method; f != nil; f = f.Down {
+ for f, it := IterMethods(u); f != nil; f = it.Next() {
if f.Embedded == 0 && (f.Sym == s || (ignorecase && strings.EqualFold(f.Sym.Name, s.Name))) {
if save != nil {
*save = f
goto out
}
- for f := u.Type; f != nil; f = f.Down {
+ for f, it := IterFields(u); f != nil; f = it.Next() {
if f.Embedded == 0 || f.Sym == nil {
continue
}
if u.Etype == TINTER {
var sl *Symlink
- for f := u.Type; f != nil; f = f.Down {
+ for f, it := IterFields(u); f != nil; f = it.Next() {
if f.Sym.Flags&SymUniq != 0 {
continue
}
u = methtype(t, 0)
if u != nil {
var sl *Symlink
- for f := u.Method; f != nil; f = f.Down {
+ for f, it := IterMethods(u); f != nil; f = it.Next() {
if f.Sym.Flags&SymUniq != 0 {
continue
}
goto out
}
- for f := u.Type; f != nil; f = f.Down {
+ for f, it := IterFields(u); f != nil; f = it.Next() {
if f.Embedded == 0 {
continue
}
// mark top-level method symbols
// so that expand1 doesn't consider them.
var f *Type
- for f = t.Method; f != nil; f = f.Down {
+ for f, it := IterMethods(t); f != nil; f = it.Next() {
f.Sym.Flags |= SymUniq
}
}
}
- for f = t.Method; f != nil; f = f.Down {
+ for f, it := IterMethods(t); f != nil; f = it.Next() {
f.Sym.Flags &^= SymUniq
}
// and then do one loop.
if t.Etype == TINTER {
- var tm *Type
- for im := iface.Type; im != nil; im = im.Down {
- for tm = t.Type; tm != nil; tm = tm.Down {
+ for im, it := IterFields(iface); im != nil; im = it.Next() {
+ for tm, it2 := IterFields(t); tm != nil; tm = it2.Next() {
if tm.Sym == im.Sym {
if Eqtype(tm.Type, im.Type) {
goto found
var imtype *Type
var followptr bool
var rcvr *Type
- for im := iface.Type; im != nil; im = im.Down {
+ for im, it := IterFields(iface); im != nil; im = it.Next() {
if im.Broke {
continue
}
if t.Etype != TSTRUCT && t.Etype != TINTER {
Fatalf("IterFields: type %v does not have fields", t)
}
- i := Iter{x: t.Type}
+ return RawIter(t.Type)
+}
+
+// IterMethods returns the first method in type t's method set
+// and an Iter value to continue iterating across the rest.
+// IterMethods does not include promoted methods.
+func IterMethods(t *Type) (*Type, Iter) {
+ // TODO(mdempsky): Validate t?
+ return RawIter(t.Method)
+}
+
+// IterAllMethods returns the first (possibly promoted) method in type t's
+// method set and an Iter value to continue iterating across the rest.
+func IterAllMethods(t *Type) (*Type, Iter) {
+ // TODO(mdempsky): Validate t?
+ return RawIter(t.Xmethod)
+}
+
+// RawIter returns field t and an Iter value to continue iterating across
+// its successor fields. Most code should instead use one of the IterXXX
+// functions above.
+func RawIter(t *Type) (*Type, Iter) {
+ i := Iter{x: t}
f := i.Next()
return f, i
}
func lookdot1(errnode *Node, s *Sym, t *Type, f *Type, dostrcmp int) *Type {
var r *Type
- for ; f != nil; f = f.Down {
+ for f, it := RawIter(f); f != nil; f = it.Next() {
if dostrcmp != 0 && f.Sym.Name == s.Name {
return f
}
}
func hasddd(t *Type) bool {
- for tl := t.Type; tl != nil; tl = tl.Down {
+ for tl, it := IterFields(t); tl != nil; tl = it.Next() {
if tl.Isddd {
return true
}
// TODO decide if we want both (for semantic reasons)
func downcount(t *Type) int {
n := 0
- for tl := t.Type; tl != nil; tl = tl.Down {
+ for tl, it := IterFields(t); tl != nil; tl = it.Next() {
n++
}
tn := n.Type.Type
var why string
- for tl := tstruct.Type; tl != nil; tl = tl.Down {
+ for tl, it2 := IterFields(tstruct); tl != nil; tl = it2.Next() {
if tl.Isddd {
for ; tn != nil; tn = tn.Down {
if assignop(tn.Type, tl.Type.Type, &why) == 0 {
}
i = 0
- for tl := tstruct.Type; tl != nil; tl = tl.Down {
+ for tl, it := IterFields(tstruct); tl != nil; tl = it.Next() {
t = tl.Type
if tl.Isddd {
if isddd {
func countfield(t *Type) int {
n := 0
- for t1 := t.Type; t1 != nil; t1 = t1.Down {
+ for t1, it := IterFields(t); t1 != nil; t1 = it.Next() {
n++
}
return n
// Inline comparisons.
var li *Node
var ri *Node
- for t1 := t.Type; t1 != nil; t1 = t1.Down {
+ for t1, it := IterFields(t); t1 != nil; t1 = it.Next() {
if isblanksym(t1.Sym) {
continue
}