From acb4d1cef14529585266df1868045f80e37ae081 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sun, 22 Nov 2020 09:59:15 -0500 Subject: [PATCH] [dev.regabi] cmd/compile: use Node getters and setters [generated] Now that we have all the getters and setters defined, use them and unexport all the actual Node fields. This is the next step toward replacing Node with an interface. [git-generate] cd src/cmd/compile/internal/gc rf ' ex . ../ir ../ssa { import "cmd/compile/internal/ir" import "cmd/compile/internal/types" import "cmd/internal/src" var n, x *ir.Node var op ir.Op var t *types.Type var f *ir.Func var m *ir.Name var s *types.Sym var p src.XPos var i int64 var e uint16 var nodes ir.Nodes n.Op = op -> n.SetOp(op) n.Left = x -> n.SetLeft(x) n.Right = x -> n.SetRight(x) n.Orig = x -> n.SetOrig(x) n.Type = t -> n.SetType(t) n.Func = f -> n.SetFunc(f) n.Name = m -> n.SetName(m) n.Sym = s -> n.SetSym(s) n.Pos = p -> n.SetPos(p) n.Xoffset = i -> n.SetXoffset(i) n.Esc = e -> n.SetEsc(e) n.Ninit.Append -> n.PtrNinit().Append n.Ninit.AppendNodes -> n.PtrNinit().AppendNodes n.Ninit.MoveNodes -> n.PtrNinit().MoveNodes n.Ninit.Prepend -> n.PtrNinit().Prepend n.Ninit.Set -> n.PtrNinit().Set n.Ninit.Set1 -> n.PtrNinit().Set1 n.Ninit.Set2 -> n.PtrNinit().Set2 n.Ninit.Set3 -> n.PtrNinit().Set3 &n.Ninit -> n.PtrNinit() n.Ninit = nodes -> n.SetNinit(nodes) n.Nbody.Append -> n.PtrNbody().Append n.Nbody.AppendNodes -> n.PtrNbody().AppendNodes n.Nbody.MoveNodes -> n.PtrNbody().MoveNodes n.Nbody.Prepend -> n.PtrNbody().Prepend n.Nbody.Set -> n.PtrNbody().Set n.Nbody.Set1 -> n.PtrNbody().Set1 n.Nbody.Set2 -> n.PtrNbody().Set2 n.Nbody.Set3 -> n.PtrNbody().Set3 &n.Nbody -> n.PtrNbody() n.Nbody = nodes -> n.SetNbody(nodes) n.List.Append -> n.PtrList().Append n.List.AppendNodes -> n.PtrList().AppendNodes n.List.MoveNodes -> n.PtrList().MoveNodes n.List.Prepend -> n.PtrList().Prepend n.List.Set -> n.PtrList().Set n.List.Set1 -> n.PtrList().Set1 n.List.Set2 -> n.PtrList().Set2 n.List.Set3 -> n.PtrList().Set3 &n.List -> n.PtrList() n.List = nodes -> n.SetList(nodes) n.Rlist.Append -> n.PtrRlist().Append n.Rlist.AppendNodes -> n.PtrRlist().AppendNodes n.Rlist.MoveNodes -> n.PtrRlist().MoveNodes n.Rlist.Prepend -> n.PtrRlist().Prepend n.Rlist.Set -> n.PtrRlist().Set n.Rlist.Set1 -> n.PtrRlist().Set1 n.Rlist.Set2 -> n.PtrRlist().Set2 n.Rlist.Set3 -> n.PtrRlist().Set3 &n.Rlist -> n.PtrRlist() n.Rlist = nodes -> n.SetRlist(nodes) } ex . ../ir ../ssa { import "cmd/compile/internal/ir" var n *ir.Node n.Op -> n.GetOp() n.Left -> n.GetLeft() n.Right -> n.GetRight() n.Orig -> n.GetOrig() n.Type -> n.GetType() n.Func -> n.GetFunc() n.Name -> n.GetName() n.Sym -> n.GetSym() n.Pos -> n.GetPos() n.Xoffset -> n.GetXoffset() n.Esc -> n.GetEsc() avoid (*ir.Node).PtrNinit avoid (*ir.Node).PtrNbody avoid (*ir.Node).PtrList avoid (*ir.Node).PtrRlist n.Ninit -> n.GetNinit() n.Nbody -> n.GetNbody() n.List -> n.GetList() n.Rlist -> n.GetRlist() } ' cd ../ir rf ' mv Node.Op Node.op mv Node.GetOp Node.Op mv Node.Left Node.left mv Node.GetLeft Node.Left mv Node.Right Node.right mv Node.GetRight Node.Right mv Node.Orig Node.orig mv Node.GetOrig Node.Orig mv Node.Type Node.typ mv Node.GetType Node.Type mv Node.Func Node.fn mv Node.GetFunc Node.Func mv Node.Name Node.name mv Node.GetName Node.Name # All uses are in other Node methods already. mv Node.E Node.e mv Node.Sym Node.sym mv Node.GetSym Node.Sym mv Node.Pos Node.pos mv Node.GetPos Node.Pos mv Node.Esc Node.esc mv Node.GetEsc Node.Esc # While we are here, rename Xoffset to more idiomatic Offset. mv Node.Xoffset Node.offset mv Node.GetXoffset Node.Offset mv Node.SetXoffset Node.SetOffset # While we are here, rename Ninit, Nbody to more idiomatic Init, Body. mv Node.Ninit Node.init mv Node.GetNinit Node.Init mv Node.PtrNinit Node.PtrInit mv Node.SetNinit Node.SetInit mv Node.Nbody Node.body mv Node.GetNbody Node.Body mv Node.PtrNbody Node.PtrBody mv Node.SetNbody Node.SetBody mv Node.List Node.list mv Node.GetList Node.List mv Node.Rlist Node.rlist mv Node.GetRlist Node.Rlist # Unexport these mv Node.SetHasOpt Node.setHasOpt mv Node.SetHasVal Node.setHasVal ' Change-Id: I9894f633375c5237a29b6d6d7b89ba181b56ca3a Reviewed-on: https://go-review.googlesource.com/c/go/+/273009 Trust: Russ Cox Run-TryBot: Russ Cox Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/gc/alg.go | 154 +- src/cmd/compile/internal/gc/align.go | 12 +- src/cmd/compile/internal/gc/bexport.go | 4 +- src/cmd/compile/internal/gc/bimport.go | 2 +- src/cmd/compile/internal/gc/closure.go | 222 +-- src/cmd/compile/internal/gc/const.go | 172 +- src/cmd/compile/internal/gc/dcl.go | 266 +-- src/cmd/compile/internal/gc/dwinl.go | 6 +- src/cmd/compile/internal/gc/embed.go | 36 +- src/cmd/compile/internal/gc/escape.go | 518 +++--- src/cmd/compile/internal/gc/export.go | 54 +- src/cmd/compile/internal/gc/gen.go | 22 +- src/cmd/compile/internal/gc/gsubr.go | 24 +- src/cmd/compile/internal/gc/iexport.go | 338 ++-- src/cmd/compile/internal/gc/iimport.go | 144 +- src/cmd/compile/internal/gc/init.go | 20 +- src/cmd/compile/internal/gc/initorder.go | 70 +- src/cmd/compile/internal/gc/inl.go | 554 +++--- src/cmd/compile/internal/gc/main.go | 40 +- src/cmd/compile/internal/gc/noder.go | 254 +-- src/cmd/compile/internal/gc/obj.go | 110 +- src/cmd/compile/internal/gc/order.go | 604 +++---- src/cmd/compile/internal/gc/pgen.go | 178 +- src/cmd/compile/internal/gc/pgen_test.go | 12 +- src/cmd/compile/internal/gc/plive.go | 48 +- src/cmd/compile/internal/gc/racewalk.go | 18 +- src/cmd/compile/internal/gc/range.go | 208 +-- src/cmd/compile/internal/gc/reflect.go | 16 +- src/cmd/compile/internal/gc/scc.go | 26 +- src/cmd/compile/internal/gc/scope.go | 6 +- src/cmd/compile/internal/gc/select.go | 192 +-- src/cmd/compile/internal/gc/sinit.go | 356 ++-- src/cmd/compile/internal/gc/ssa.go | 1082 ++++++------ src/cmd/compile/internal/gc/subr.go | 206 +-- src/cmd/compile/internal/gc/swt.go | 278 +-- src/cmd/compile/internal/gc/typecheck.go | 1970 +++++++++++----------- src/cmd/compile/internal/gc/universe.go | 38 +- src/cmd/compile/internal/gc/unsafe.go | 38 +- src/cmd/compile/internal/gc/walk.go | 1404 +++++++-------- src/cmd/compile/internal/ir/dump.go | 2 +- src/cmd/compile/internal/ir/fmt.go | 402 ++--- src/cmd/compile/internal/ir/node.go | 266 +-- src/cmd/compile/internal/ir/val.go | 6 +- src/cmd/compile/internal/ssa/nilcheck.go | 2 +- 44 files changed, 5191 insertions(+), 5189 deletions(-) diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go index cf82b9d591..ffd1682b35 100644 --- a/src/cmd/compile/internal/gc/alg.go +++ b/src/cmd/compile/internal/gc/alg.go @@ -293,15 +293,15 @@ func genhash(t *types.Type) *obj.LSym { // func sym(p *T, h uintptr) uintptr tfn := ir.Nod(ir.OTFUNC, nil, nil) - tfn.List.Set2( + tfn.PtrList().Set2( namedfield("p", types.NewPtr(t)), namedfield("h", types.Types[types.TUINTPTR]), ) - tfn.Rlist.Set1(anonfield(types.Types[types.TUINTPTR])) + tfn.PtrRlist().Set1(anonfield(types.Types[types.TUINTPTR])) fn := dclfunc(sym, tfn) - np := ir.AsNode(tfn.Type.Params().Field(0).Nname) - nh := ir.AsNode(tfn.Type.Params().Field(1).Nname) + np := ir.AsNode(tfn.Type().Params().Field(0).Nname) + nh := ir.AsNode(tfn.Type().Params().Field(1).Nname) switch t.Etype { case types.TARRAY: @@ -312,11 +312,11 @@ func genhash(t *types.Type) *obj.LSym { n := ir.Nod(ir.ORANGE, nil, ir.Nod(ir.ODEREF, np, nil)) ni := NewName(lookup("i")) - ni.Type = types.Types[types.TINT] - n.List.Set1(ni) + ni.SetType(types.Types[types.TINT]) + n.PtrList().Set1(ni) n.SetColas(true) - colasdefn(n.List.Slice(), n) - ni = n.List.First() + colasdefn(n.List().Slice(), n) + ni = n.List().First() // h = hashel(&p[i], h) call := ir.Nod(ir.OCALL, hashel, nil) @@ -324,11 +324,11 @@ func genhash(t *types.Type) *obj.LSym { nx := ir.Nod(ir.OINDEX, np, ni) nx.SetBounded(true) na := ir.Nod(ir.OADDR, nx, nil) - call.List.Append(na) - call.List.Append(nh) - n.Nbody.Append(ir.Nod(ir.OAS, nh, call)) + call.PtrList().Append(na) + call.PtrList().Append(nh) + n.PtrBody().Append(ir.Nod(ir.OAS, nh, call)) - fn.Nbody.Append(n) + fn.PtrBody().Append(n) case types.TSTRUCT: // Walk the struct using memhash for runs of AMEM @@ -348,9 +348,9 @@ func genhash(t *types.Type) *obj.LSym { call := ir.Nod(ir.OCALL, hashel, nil) nx := nodSym(ir.OXDOT, np, f.Sym) // TODO: fields from other packages? na := ir.Nod(ir.OADDR, nx, nil) - call.List.Append(na) - call.List.Append(nh) - fn.Nbody.Append(ir.Nod(ir.OAS, nh, call)) + call.PtrList().Append(na) + call.PtrList().Append(nh) + fn.PtrBody().Append(ir.Nod(ir.OAS, nh, call)) i++ continue } @@ -363,37 +363,37 @@ func genhash(t *types.Type) *obj.LSym { call := ir.Nod(ir.OCALL, hashel, nil) nx := nodSym(ir.OXDOT, np, f.Sym) // TODO: fields from other packages? na := ir.Nod(ir.OADDR, nx, nil) - call.List.Append(na) - call.List.Append(nh) - call.List.Append(nodintconst(size)) - fn.Nbody.Append(ir.Nod(ir.OAS, nh, call)) + call.PtrList().Append(na) + call.PtrList().Append(nh) + call.PtrList().Append(nodintconst(size)) + fn.PtrBody().Append(ir.Nod(ir.OAS, nh, call)) i = next } } r := ir.Nod(ir.ORETURN, nil, nil) - r.List.Append(nh) - fn.Nbody.Append(r) + r.PtrList().Append(nh) + fn.PtrBody().Append(r) if base.Flag.LowerR != 0 { - ir.DumpList("genhash body", fn.Nbody) + ir.DumpList("genhash body", fn.Body()) } funcbody() - fn.Func.SetDupok(true) + fn.Func().SetDupok(true) fn = typecheck(fn, ctxStmt) Curfn = fn - typecheckslice(fn.Nbody.Slice(), ctxStmt) + typecheckslice(fn.Body().Slice(), ctxStmt) Curfn = nil if base.Debug.DclStack != 0 { testdclstack() } - fn.Func.SetNilCheckDisabled(true) + fn.Func().SetNilCheckDisabled(true) xtop = append(xtop, fn) // Build closure. It doesn't close over any variables, so @@ -432,12 +432,12 @@ func hashfor(t *types.Type) *ir.Node { n := NewName(sym) setNodeNameFunc(n) - n.Type = functype(nil, []*ir.Node{ + n.SetType(functype(nil, []*ir.Node{ anonfield(types.NewPtr(t)), anonfield(types.Types[types.TUINTPTR]), }, []*ir.Node{ anonfield(types.Types[types.TUINTPTR]), - }) + })) return n } @@ -522,16 +522,16 @@ func geneq(t *types.Type) *obj.LSym { // func sym(p, q *T) bool tfn := ir.Nod(ir.OTFUNC, nil, nil) - tfn.List.Set2( + tfn.PtrList().Set2( namedfield("p", types.NewPtr(t)), namedfield("q", types.NewPtr(t)), ) - tfn.Rlist.Set1(namedfield("r", types.Types[types.TBOOL])) + tfn.PtrRlist().Set1(namedfield("r", types.Types[types.TBOOL])) fn := dclfunc(sym, tfn) - np := ir.AsNode(tfn.Type.Params().Field(0).Nname) - nq := ir.AsNode(tfn.Type.Params().Field(1).Nname) - nr := ir.AsNode(tfn.Type.Results().Field(0).Nname) + np := ir.AsNode(tfn.Type().Params().Field(0).Nname) + nq := ir.AsNode(tfn.Type().Params().Field(1).Nname) + nr := ir.AsNode(tfn.Type().Results().Field(0).Nname) // Label to jump to if an equality test fails. neq := autolabel(".neq") @@ -573,11 +573,11 @@ func geneq(t *types.Type) *obj.LSym { // pi := p[i] pi := ir.Nod(ir.OINDEX, np, i) pi.SetBounded(true) - pi.Type = t.Elem() + pi.SetType(t.Elem()) // qi := q[i] qi := ir.Nod(ir.OINDEX, nq, i) qi.SetBounded(true) - qi.Type = t.Elem() + qi.SetType(t.Elem()) return eq(pi, qi) } @@ -590,11 +590,11 @@ func geneq(t *types.Type) *obj.LSym { for i := int64(0); i < nelem; i++ { // if check {} else { goto neq } nif := ir.Nod(ir.OIF, checkIdx(nodintconst(i)), nil) - nif.Rlist.Append(nodSym(ir.OGOTO, nil, neq)) - fn.Nbody.Append(nif) + nif.PtrRlist().Append(nodSym(ir.OGOTO, nil, neq)) + fn.PtrBody().Append(nif) } if last { - fn.Nbody.Append(ir.Nod(ir.OAS, nr, checkIdx(nodintconst(nelem)))) + fn.PtrBody().Append(ir.Nod(ir.OAS, nr, checkIdx(nodintconst(nelem)))) } } else { // Generate a for loop. @@ -604,14 +604,14 @@ func geneq(t *types.Type) *obj.LSym { cond := ir.Nod(ir.OLT, i, nodintconst(nelem)) post := ir.Nod(ir.OAS, i, ir.Nod(ir.OADD, i, nodintconst(1))) loop := ir.Nod(ir.OFOR, cond, post) - loop.Ninit.Append(init) + loop.PtrInit().Append(init) // if eq(pi, qi) {} else { goto neq } nif := ir.Nod(ir.OIF, checkIdx(i), nil) - nif.Rlist.Append(nodSym(ir.OGOTO, nil, neq)) - loop.Nbody.Append(nif) - fn.Nbody.Append(loop) + nif.PtrRlist().Append(nodSym(ir.OGOTO, nil, neq)) + loop.PtrBody().Append(nif) + fn.PtrBody().Append(loop) if last { - fn.Nbody.Append(ir.Nod(ir.OAS, nr, nodbool(true))) + fn.PtrBody().Append(ir.Nod(ir.OAS, nr, nodbool(true))) } } } @@ -712,7 +712,7 @@ func geneq(t *types.Type) *obj.LSym { var flatConds []*ir.Node for _, c := range conds { isCall := func(n *ir.Node) bool { - return n.Op == ir.OCALL || n.Op == ir.OCALLFUNC + return n.Op() == ir.OCALL || n.Op() == ir.OCALLFUNC } sort.SliceStable(c, func(i, j int) bool { return !isCall(c[i]) && isCall(c[j]) @@ -721,51 +721,51 @@ func geneq(t *types.Type) *obj.LSym { } if len(flatConds) == 0 { - fn.Nbody.Append(ir.Nod(ir.OAS, nr, nodbool(true))) + fn.PtrBody().Append(ir.Nod(ir.OAS, nr, nodbool(true))) } else { for _, c := range flatConds[:len(flatConds)-1] { // if cond {} else { goto neq } n := ir.Nod(ir.OIF, c, nil) - n.Rlist.Append(nodSym(ir.OGOTO, nil, neq)) - fn.Nbody.Append(n) + n.PtrRlist().Append(nodSym(ir.OGOTO, nil, neq)) + fn.PtrBody().Append(n) } - fn.Nbody.Append(ir.Nod(ir.OAS, nr, flatConds[len(flatConds)-1])) + fn.PtrBody().Append(ir.Nod(ir.OAS, nr, flatConds[len(flatConds)-1])) } } // ret: // return ret := autolabel(".ret") - fn.Nbody.Append(nodSym(ir.OLABEL, nil, ret)) - fn.Nbody.Append(ir.Nod(ir.ORETURN, nil, nil)) + fn.PtrBody().Append(nodSym(ir.OLABEL, nil, ret)) + fn.PtrBody().Append(ir.Nod(ir.ORETURN, nil, nil)) // neq: // r = false // return (or goto ret) - fn.Nbody.Append(nodSym(ir.OLABEL, nil, neq)) - fn.Nbody.Append(ir.Nod(ir.OAS, nr, nodbool(false))) + fn.PtrBody().Append(nodSym(ir.OLABEL, nil, neq)) + fn.PtrBody().Append(ir.Nod(ir.OAS, nr, nodbool(false))) if EqCanPanic(t) || hasCall(fn) { // Epilogue is large, so share it with the equal case. - fn.Nbody.Append(nodSym(ir.OGOTO, nil, ret)) + fn.PtrBody().Append(nodSym(ir.OGOTO, nil, ret)) } else { // Epilogue is small, so don't bother sharing. - fn.Nbody.Append(ir.Nod(ir.ORETURN, nil, nil)) + fn.PtrBody().Append(ir.Nod(ir.ORETURN, nil, nil)) } // TODO(khr): the epilogue size detection condition above isn't perfect. // We should really do a generic CL that shares epilogues across // the board. See #24936. if base.Flag.LowerR != 0 { - ir.DumpList("geneq body", fn.Nbody) + ir.DumpList("geneq body", fn.Body()) } funcbody() - fn.Func.SetDupok(true) + fn.Func().SetDupok(true) fn = typecheck(fn, ctxStmt) Curfn = fn - typecheckslice(fn.Nbody.Slice(), ctxStmt) + typecheckslice(fn.Body().Slice(), ctxStmt) Curfn = nil if base.Debug.DclStack != 0 { @@ -776,7 +776,7 @@ func geneq(t *types.Type) *obj.LSym { // We are comparing a struct or an array, // neither of which can be nil, and our comparisons // are shallow. - fn.Func.SetNilCheckDisabled(true) + fn.Func().SetNilCheckDisabled(true) xtop = append(xtop, fn) // Generate a closure which points at the function we just generated. @@ -786,31 +786,31 @@ func geneq(t *types.Type) *obj.LSym { } func hasCall(n *ir.Node) bool { - if n.Op == ir.OCALL || n.Op == ir.OCALLFUNC { + if n.Op() == ir.OCALL || n.Op() == ir.OCALLFUNC { return true } - if n.Left != nil && hasCall(n.Left) { + if n.Left() != nil && hasCall(n.Left()) { return true } - if n.Right != nil && hasCall(n.Right) { + if n.Right() != nil && hasCall(n.Right()) { return true } - for _, x := range n.Ninit.Slice() { + for _, x := range n.Init().Slice() { if hasCall(x) { return true } } - for _, x := range n.Nbody.Slice() { + for _, x := range n.Body().Slice() { if hasCall(x) { return true } } - for _, x := range n.List.Slice() { + for _, x := range n.List().Slice() { if hasCall(x) { return true } } - for _, x := range n.Rlist.Slice() { + for _, x := range n.Rlist().Slice() { if hasCall(x) { return true } @@ -844,12 +844,12 @@ func eqstring(s, t *ir.Node) (eqlen, eqmem *ir.Node) { fn := syslook("memequal") fn = substArgTypes(fn, types.Types[types.TUINT8], types.Types[types.TUINT8]) call := ir.Nod(ir.OCALL, fn, nil) - call.List.Append(sptr, tptr, ir.Copy(slen)) + call.PtrList().Append(sptr, tptr, ir.Copy(slen)) call = typecheck(call, ctxExpr|ctxMultiOK) cmp := ir.Nod(ir.OEQ, slen, tlen) cmp = typecheck(cmp, ctxExpr) - cmp.Type = types.Types[types.TBOOL] + cmp.SetType(types.Types[types.TBOOL]) return cmp, call } @@ -860,13 +860,13 @@ func eqstring(s, t *ir.Node) (eqlen, eqmem *ir.Node) { // which can be used to construct interface equality comparison. // eqtab must be evaluated before eqdata, and shortcircuiting is required. func eqinterface(s, t *ir.Node) (eqtab, eqdata *ir.Node) { - if !types.Identical(s.Type, t.Type) { - base.Fatalf("eqinterface %v %v", s.Type, t.Type) + if !types.Identical(s.Type(), t.Type()) { + base.Fatalf("eqinterface %v %v", s.Type(), t.Type()) } // func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool) // func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool) var fn *ir.Node - if s.Type.IsEmptyInterface() { + if s.Type().IsEmptyInterface() { fn = syslook("efaceeq") } else { fn = syslook("ifaceeq") @@ -876,18 +876,18 @@ func eqinterface(s, t *ir.Node) (eqtab, eqdata *ir.Node) { ttab := ir.Nod(ir.OITAB, t, nil) sdata := ir.Nod(ir.OIDATA, s, nil) tdata := ir.Nod(ir.OIDATA, t, nil) - sdata.Type = types.Types[types.TUNSAFEPTR] - tdata.Type = types.Types[types.TUNSAFEPTR] + sdata.SetType(types.Types[types.TUNSAFEPTR]) + tdata.SetType(types.Types[types.TUNSAFEPTR]) sdata.SetTypecheck(1) tdata.SetTypecheck(1) call := ir.Nod(ir.OCALL, fn, nil) - call.List.Append(stab, sdata, tdata) + call.PtrList().Append(stab, sdata, tdata) call = typecheck(call, ctxExpr|ctxMultiOK) cmp := ir.Nod(ir.OEQ, stab, ttab) cmp = typecheck(cmp, ctxExpr) - cmp.Type = types.Types[types.TBOOL] + cmp.SetType(types.Types[types.TBOOL]) return cmp, call } @@ -899,12 +899,12 @@ func eqmem(p *ir.Node, q *ir.Node, field *types.Sym, size int64) *ir.Node { nx = typecheck(nx, ctxExpr) ny = typecheck(ny, ctxExpr) - fn, needsize := eqmemfunc(size, nx.Type.Elem()) + fn, needsize := eqmemfunc(size, nx.Type().Elem()) call := ir.Nod(ir.OCALL, fn, nil) - call.List.Append(nx) - call.List.Append(ny) + call.PtrList().Append(nx) + call.PtrList().Append(ny) if needsize { - call.List.Append(nodintconst(size)) + call.PtrList().Append(nodintconst(size)) } return call diff --git a/src/cmd/compile/internal/gc/align.go b/src/cmd/compile/internal/gc/align.go index 1bc8bf238f..edf7d263a3 100644 --- a/src/cmd/compile/internal/gc/align.go +++ b/src/cmd/compile/internal/gc/align.go @@ -126,11 +126,11 @@ func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 { // NOTE(rsc): This comment may be stale. // It's possible the ordering has changed and this is // now the common case. I'm not sure. - if n.Name.Param.Stackcopy != nil { - n.Name.Param.Stackcopy.Xoffset = o - n.Xoffset = 0 + if n.Name().Param.Stackcopy != nil { + n.Name().Param.Stackcopy.SetOffset(o) + n.SetOffset(0) } else { - n.Xoffset = o + n.SetOffset(o) } } @@ -198,7 +198,7 @@ func findTypeLoop(t *types.Type, path *[]*types.Type) bool { } *path = append(*path, t) - if p := ir.AsNode(t.Nod).Name.Param; p != nil && findTypeLoop(p.Ntype.Type, path) { + if p := ir.AsNode(t.Nod).Name().Param; p != nil && findTypeLoop(p.Ntype.Type(), path) { return true } *path = (*path)[:len(*path)-1] @@ -308,7 +308,7 @@ func dowidth(t *types.Type) { lno := base.Pos if ir.AsNode(t.Nod) != nil { - base.Pos = ir.AsNode(t.Nod).Pos + base.Pos = ir.AsNode(t.Nod).Pos() } t.Width = -2 diff --git a/src/cmd/compile/internal/gc/bexport.go b/src/cmd/compile/internal/gc/bexport.go index ff33c6b5fc..e36903cbe0 100644 --- a/src/cmd/compile/internal/gc/bexport.go +++ b/src/cmd/compile/internal/gc/bexport.go @@ -15,11 +15,11 @@ type exporter struct { // markObject visits a reachable object. func (p *exporter) markObject(n *ir.Node) { - if n.Op == ir.ONAME && n.Class() == ir.PFUNC { + if n.Op() == ir.ONAME && n.Class() == ir.PFUNC { inlFlood(n) } - p.markType(n.Type) + p.markType(n.Type()) } // markType recursively visits types reachable from t to identify diff --git a/src/cmd/compile/internal/gc/bimport.go b/src/cmd/compile/internal/gc/bimport.go index e2dd276f46..603710d6b1 100644 --- a/src/cmd/compile/internal/gc/bimport.go +++ b/src/cmd/compile/internal/gc/bimport.go @@ -10,7 +10,7 @@ import ( ) func npos(pos src.XPos, n *ir.Node) *ir.Node { - n.Pos = pos + n.SetPos(pos) return n } diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go index e68d710363..1b926ec17e 100644 --- a/src/cmd/compile/internal/gc/closure.go +++ b/src/cmd/compile/internal/gc/closure.go @@ -18,14 +18,14 @@ func (p *noder) funcLit(expr *syntax.FuncLit) *ir.Node { ntype := p.typeExpr(expr.Type) dcl := p.nod(expr, ir.ODCLFUNC, nil, nil) - fn := dcl.Func + fn := dcl.Func() fn.SetIsHiddenClosure(Curfn != nil) - fn.Nname = newfuncnamel(p.pos(expr), ir.BlankNode.Sym, fn) // filled in by typecheckclosure - fn.Nname.Name.Param.Ntype = xtype - fn.Nname.Name.Defn = dcl + fn.Nname = newfuncnamel(p.pos(expr), ir.BlankNode.Sym(), fn) // filled in by typecheckclosure + fn.Nname.Name().Param.Ntype = xtype + fn.Nname.Name().Defn = dcl clo := p.nod(expr, ir.OCLOSURE, nil, nil) - clo.Func = fn + clo.SetFunc(fn) fn.ClosureType = ntype fn.OClosure = clo @@ -37,8 +37,8 @@ func (p *noder) funcLit(expr *syntax.FuncLit) *ir.Node { // make the list of pointers for the closure call. for _, v := range fn.ClosureVars.Slice() { // Unlink from v1; see comment in syntax.go type Param for these fields. - v1 := v.Name.Defn - v1.Name.Param.Innermost = v.Name.Param.Outer + v1 := v.Name().Defn + v1.Name().Param.Innermost = v.Name().Param.Outer // If the closure usage of v is not dense, // we need to make it dense; now that we're out @@ -68,7 +68,7 @@ func (p *noder) funcLit(expr *syntax.FuncLit) *ir.Node { // obtains f3's v, creating it if necessary (as it is in the example). // // capturevars will decide whether to use v directly or &v. - v.Name.Param.Outer = oldname(v.Sym) + v.Name().Param.Outer = oldname(v.Sym()) } return clo @@ -79,7 +79,7 @@ func (p *noder) funcLit(expr *syntax.FuncLit) *ir.Node { // TODO: This creation of the named function should probably really be done in a // separate pass from type-checking. func typecheckclosure(clo *ir.Node, top int) { - fn := clo.Func + fn := clo.Func() dcl := fn.Decl // Set current associated iota value, so iota can be used inside // function in ConstSpec, see issue #22344 @@ -88,7 +88,7 @@ func typecheckclosure(clo *ir.Node, top int) { } fn.ClosureType = typecheck(fn.ClosureType, ctxType) - clo.Type = fn.ClosureType.Type + clo.SetType(fn.ClosureType.Type()) fn.ClosureCalled = top&ctxCallee != 0 // Do not typecheck dcl twice, otherwise, we will end up pushing @@ -99,22 +99,22 @@ func typecheckclosure(clo *ir.Node, top int) { } for _, ln := range fn.ClosureVars.Slice() { - n := ln.Name.Defn - if !n.Name.Captured() { - n.Name.SetCaptured(true) - if n.Name.Decldepth == 0 { + n := ln.Name().Defn + if !n.Name().Captured() { + n.Name().SetCaptured(true) + if n.Name().Decldepth == 0 { base.Fatalf("typecheckclosure: var %S does not have decldepth assigned", n) } // Ignore assignments to the variable in straightline code // preceding the first capturing by a closure. - if n.Name.Decldepth == decldepth { - n.Name.SetAssigned(false) + if n.Name().Decldepth == decldepth { + n.Name().SetAssigned(false) } } } - fn.Nname.Sym = closurename(Curfn) + fn.Nname.SetSym(closurename(Curfn)) setNodeNameFunc(fn.Nname) dcl = typecheck(dcl, ctxStmt) @@ -122,12 +122,12 @@ func typecheckclosure(clo *ir.Node, top int) { // At top level (in a variable initialization: curfn==nil) we're not // ready to type check code yet; we'll check it later, because the // underlying closure function we create is added to xtop. - if Curfn != nil && clo.Type != nil { + if Curfn != nil && clo.Type() != nil { oldfn := Curfn Curfn = dcl olddd := decldepth decldepth = 1 - typecheckslice(dcl.Nbody.Slice(), ctxStmt) + typecheckslice(dcl.Body().Slice(), ctxStmt) decldepth = olddd Curfn = oldfn } @@ -146,7 +146,7 @@ func closurename(outerfunc *ir.Node) *types.Sym { gen := &globClosgen if outerfunc != nil { - if outerfunc.Func.OClosure != nil { + if outerfunc.Func().OClosure != nil { prefix = "" } @@ -155,8 +155,8 @@ func closurename(outerfunc *ir.Node) *types.Sym { // There may be multiple functions named "_". In those // cases, we can't use their individual Closgens as it // would lead to name clashes. - if !ir.IsBlank(outerfunc.Func.Nname) { - gen = &outerfunc.Func.Closgen + if !ir.IsBlank(outerfunc.Func().Nname) { + gen = &outerfunc.Func().Closgen } } @@ -174,12 +174,12 @@ var capturevarscomplete bool // after capturing (effectively constant). func capturevars(dcl *ir.Node) { lno := base.Pos - base.Pos = dcl.Pos - fn := dcl.Func + base.Pos = dcl.Pos() + fn := dcl.Func() cvars := fn.ClosureVars.Slice() out := cvars[:0] for _, v := range cvars { - if v.Type == nil { + if v.Type() == nil { // If v.Type is nil, it means v looked like it // was going to be used in the closure, but // isn't. This happens in struct literals like @@ -192,29 +192,29 @@ func capturevars(dcl *ir.Node) { // type check the & of closed variables outside the closure, // so that the outer frame also grabs them and knows they escape. - dowidth(v.Type) + dowidth(v.Type()) - outer := v.Name.Param.Outer - outermost := v.Name.Defn + outer := v.Name().Param.Outer + outermost := v.Name().Defn // out parameters will be assigned to implicitly upon return. - if outermost.Class() != ir.PPARAMOUT && !outermost.Name.Addrtaken() && !outermost.Name.Assigned() && v.Type.Width <= 128 { - v.Name.SetByval(true) + if outermost.Class() != ir.PPARAMOUT && !outermost.Name().Addrtaken() && !outermost.Name().Assigned() && v.Type().Width <= 128 { + v.Name().SetByval(true) } else { - outermost.Name.SetAddrtaken(true) + outermost.Name().SetAddrtaken(true) outer = ir.Nod(ir.OADDR, outer, nil) } if base.Flag.LowerM > 1 { var name *types.Sym - if v.Name.Curfn != nil && v.Name.Curfn.Func.Nname != nil { - name = v.Name.Curfn.Func.Nname.Sym + if v.Name().Curfn != nil && v.Name().Curfn.Func().Nname != nil { + name = v.Name().Curfn.Func().Nname.Sym() } how := "ref" - if v.Name.Byval() { + if v.Name().Byval() { how = "value" } - base.WarnfAt(v.Pos, "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym, outermost.Name.Addrtaken(), outermost.Name.Assigned(), int32(v.Type.Width)) + base.WarnfAt(v.Pos(), "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym(), outermost.Name().Addrtaken(), outermost.Name().Assigned(), int32(v.Type().Width)) } outer = typecheck(outer, ctxExpr) @@ -229,8 +229,8 @@ func capturevars(dcl *ir.Node) { // It transform closure bodies to properly reference captured variables. func transformclosure(dcl *ir.Node) { lno := base.Pos - base.Pos = dcl.Pos - fn := dcl.Func + base.Pos = dcl.Pos() + fn := dcl.Func() if fn.ClosureCalled { // If the closure is directly called, we transform it to a plain function call @@ -255,33 +255,33 @@ func transformclosure(dcl *ir.Node) { var params []*types.Field var decls []*ir.Node for _, v := range fn.ClosureVars.Slice() { - if !v.Name.Byval() { + if !v.Name().Byval() { // If v of type T is captured by reference, // we introduce function param &v *T // and v remains PAUTOHEAP with &v heapaddr // (accesses will implicitly deref &v). - addr := NewName(lookup("&" + v.Sym.Name)) - addr.Type = types.NewPtr(v.Type) - v.Name.Param.Heapaddr = addr + addr := NewName(lookup("&" + v.Sym().Name)) + addr.SetType(types.NewPtr(v.Type())) + v.Name().Param.Heapaddr = addr v = addr } v.SetClass(ir.PPARAM) decls = append(decls, v) - fld := types.NewField(src.NoXPos, v.Sym, v.Type) + fld := types.NewField(src.NoXPos, v.Sym(), v.Type()) fld.Nname = ir.AsTypesNode(v) params = append(params, fld) } if len(params) > 0 { // Prepend params and decls. - f.Type.Params().SetFields(append(params, f.Type.Params().FieldSlice()...)) + f.Type().Params().SetFields(append(params, f.Type().Params().FieldSlice()...)) fn.Dcl = append(decls, fn.Dcl...) } - dowidth(f.Type) - dcl.Type = f.Type // update type of ODCLFUNC + dowidth(f.Type()) + dcl.SetType(f.Type()) // update type of ODCLFUNC } else { // The closure is not called, so it is going to stay as closure. var body []*ir.Node @@ -290,15 +290,15 @@ func transformclosure(dcl *ir.Node) { // cv refers to the field inside of closure OSTRUCTLIT. cv := ir.Nod(ir.OCLOSUREVAR, nil, nil) - cv.Type = v.Type - if !v.Name.Byval() { - cv.Type = types.NewPtr(v.Type) + cv.SetType(v.Type()) + if !v.Name().Byval() { + cv.SetType(types.NewPtr(v.Type())) } - offset = Rnd(offset, int64(cv.Type.Align)) - cv.Xoffset = offset - offset += cv.Type.Width + offset = Rnd(offset, int64(cv.Type().Align)) + cv.SetOffset(offset) + offset += cv.Type().Width - if v.Name.Byval() && v.Type.Width <= int64(2*Widthptr) { + if v.Name().Byval() && v.Type().Width <= int64(2*Widthptr) { // If it is a small variable captured by value, downgrade it to PAUTO. v.SetClass(ir.PAUTO) fn.Dcl = append(fn.Dcl, v) @@ -306,14 +306,14 @@ func transformclosure(dcl *ir.Node) { } else { // Declare variable holding addresses taken from closure // and initialize in entry prologue. - addr := NewName(lookup("&" + v.Sym.Name)) - addr.Type = types.NewPtr(v.Type) + addr := NewName(lookup("&" + v.Sym().Name)) + addr.SetType(types.NewPtr(v.Type())) addr.SetClass(ir.PAUTO) - addr.Name.SetUsed(true) - addr.Name.Curfn = dcl + addr.Name().SetUsed(true) + addr.Name().Curfn = dcl fn.Dcl = append(fn.Dcl, addr) - v.Name.Param.Heapaddr = addr - if v.Name.Byval() { + v.Name().Param.Heapaddr = addr + if v.Name().Byval() { cv = ir.Nod(ir.OADDR, cv, nil) } body = append(body, ir.Nod(ir.OAS, addr, cv)) @@ -333,21 +333,21 @@ func transformclosure(dcl *ir.Node) { // hasemptycvars reports whether closure clo has an // empty list of captured vars. func hasemptycvars(clo *ir.Node) bool { - return clo.Func.ClosureVars.Len() == 0 + return clo.Func().ClosureVars.Len() == 0 } // closuredebugruntimecheck applies boilerplate checks for debug flags // and compiling runtime func closuredebugruntimecheck(clo *ir.Node) { if base.Debug.Closure > 0 { - if clo.Esc == EscHeap { - base.WarnfAt(clo.Pos, "heap closure, captured vars = %v", clo.Func.ClosureVars) + if clo.Esc() == EscHeap { + base.WarnfAt(clo.Pos(), "heap closure, captured vars = %v", clo.Func().ClosureVars) } else { - base.WarnfAt(clo.Pos, "stack closure, captured vars = %v", clo.Func.ClosureVars) + base.WarnfAt(clo.Pos(), "stack closure, captured vars = %v", clo.Func().ClosureVars) } } - if base.Flag.CompilingRuntime && clo.Esc == EscHeap { - base.ErrorfAt(clo.Pos, "heap-allocated closure, not allowed in runtime") + if base.Flag.CompilingRuntime && clo.Esc() == EscHeap { + base.ErrorfAt(clo.Pos(), "heap-allocated closure, not allowed in runtime") } } @@ -371,12 +371,12 @@ func closureType(clo *ir.Node) *types.Type { fields := []*ir.Node{ namedfield(".F", types.Types[types.TUINTPTR]), } - for _, v := range clo.Func.ClosureVars.Slice() { - typ := v.Type - if !v.Name.Byval() { + for _, v := range clo.Func().ClosureVars.Slice() { + typ := v.Type() + if !v.Name().Byval() { typ = types.NewPtr(typ) } - fields = append(fields, symfield(v.Sym, typ)) + fields = append(fields, symfield(v.Sym(), typ)) } typ := tostruct(fields) typ.SetNoalg(true) @@ -384,12 +384,12 @@ func closureType(clo *ir.Node) *types.Type { } func walkclosure(clo *ir.Node, init *ir.Nodes) *ir.Node { - fn := clo.Func + fn := clo.Func() // If no closure vars, don't bother wrapping. if hasemptycvars(clo) { if base.Debug.Closure > 0 { - base.WarnfAt(clo.Pos, "closure converted to global") + base.WarnfAt(clo.Pos(), "closure converted to global") } return fn.Nname } @@ -398,21 +398,21 @@ func walkclosure(clo *ir.Node, init *ir.Nodes) *ir.Node { typ := closureType(clo) clos := ir.Nod(ir.OCOMPLIT, nil, typenod(typ)) - clos.Esc = clo.Esc - clos.List.Set(append([]*ir.Node{ir.Nod(ir.OCFUNC, fn.Nname, nil)}, fn.ClosureEnter.Slice()...)) + clos.SetEsc(clo.Esc()) + clos.PtrList().Set(append([]*ir.Node{ir.Nod(ir.OCFUNC, fn.Nname, nil)}, fn.ClosureEnter.Slice()...)) clos = ir.Nod(ir.OADDR, clos, nil) - clos.Esc = clo.Esc + clos.SetEsc(clo.Esc()) // Force type conversion from *struct to the func type. - clos = convnop(clos, clo.Type) + clos = convnop(clos, clo.Type()) // non-escaping temp to use, if any. if x := prealloc[clo]; x != nil { - if !types.Identical(typ, x.Type) { + if !types.Identical(typ, x.Type()) { panic("closure type does not match order's assigned type") } - clos.Left.Right = x + clos.Left().SetRight(x) delete(prealloc, clo) } @@ -420,7 +420,7 @@ func walkclosure(clo *ir.Node, init *ir.Nodes) *ir.Node { } func typecheckpartialcall(dot *ir.Node, sym *types.Sym) { - switch dot.Op { + switch dot.Op() { case ir.ODOTINTER, ir.ODOTMETH: break @@ -429,19 +429,19 @@ func typecheckpartialcall(dot *ir.Node, sym *types.Sym) { } // Create top-level function. - dcl := makepartialcall(dot, dot.Type, sym) - dcl.Func.SetWrapper(true) - dot.Op = ir.OCALLPART - dot.Right = NewName(sym) - dot.Type = dcl.Type - dot.Func = dcl.Func + dcl := makepartialcall(dot, dot.Type(), sym) + dcl.Func().SetWrapper(true) + dot.SetOp(ir.OCALLPART) + dot.SetRight(NewName(sym)) + dot.SetType(dcl.Type()) + dot.SetFunc(dcl.Func()) dot.SetOpt(nil) // clear types.Field from ODOTMETH } // makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed // for partial calls. func makepartialcall(dot *ir.Node, t0 *types.Type, meth *types.Sym) *ir.Node { - rcvrtype := dot.Left.Type + rcvrtype := dot.Left().Type() sym := methodSymSuffix(rcvrtype, meth, "-fm") if sym.Uniq() { @@ -465,52 +465,52 @@ func makepartialcall(dot *ir.Node, t0 *types.Type, meth *types.Sym) *ir.Node { // case. See issue 29389. tfn := ir.Nod(ir.OTFUNC, nil, nil) - tfn.List.Set(structargs(t0.Params(), true)) - tfn.Rlist.Set(structargs(t0.Results(), false)) + tfn.PtrList().Set(structargs(t0.Params(), true)) + tfn.PtrRlist().Set(structargs(t0.Results(), false)) dcl := dclfunc(sym, tfn) - fn := dcl.Func + fn := dcl.Func() fn.SetDupok(true) fn.SetNeedctxt(true) - tfn.Type.SetPkg(t0.Pkg()) + tfn.Type().SetPkg(t0.Pkg()) // Declare and initialize variable holding receiver. cv := ir.Nod(ir.OCLOSUREVAR, nil, nil) - cv.Type = rcvrtype - cv.Xoffset = Rnd(int64(Widthptr), int64(cv.Type.Align)) + cv.SetType(rcvrtype) + cv.SetOffset(Rnd(int64(Widthptr), int64(cv.Type().Align))) ptr := NewName(lookup(".this")) declare(ptr, ir.PAUTO) - ptr.Name.SetUsed(true) + ptr.Name().SetUsed(true) var body []*ir.Node if rcvrtype.IsPtr() || rcvrtype.IsInterface() { - ptr.Type = rcvrtype + ptr.SetType(rcvrtype) body = append(body, ir.Nod(ir.OAS, ptr, cv)) } else { - ptr.Type = types.NewPtr(rcvrtype) + ptr.SetType(types.NewPtr(rcvrtype)) body = append(body, ir.Nod(ir.OAS, ptr, ir.Nod(ir.OADDR, cv, nil))) } call := ir.Nod(ir.OCALL, nodSym(ir.OXDOT, ptr, meth), nil) - call.List.Set(paramNnames(tfn.Type)) - call.SetIsDDD(tfn.Type.IsVariadic()) + call.PtrList().Set(paramNnames(tfn.Type())) + call.SetIsDDD(tfn.Type().IsVariadic()) if t0.NumResults() != 0 { n := ir.Nod(ir.ORETURN, nil, nil) - n.List.Set1(call) + n.PtrList().Set1(call) call = n } body = append(body, call) - dcl.Nbody.Set(body) + dcl.PtrBody().Set(body) funcbody() dcl = typecheck(dcl, ctxStmt) // Need to typecheck the body of the just-generated wrapper. // typecheckslice() requires that Curfn is set when processing an ORETURN. Curfn = dcl - typecheckslice(dcl.Nbody.Slice(), ctxStmt) + typecheckslice(dcl.Body().Slice(), ctxStmt) sym.Def = ir.AsTypesNode(dcl) xtop = append(xtop, dcl) Curfn = savecurfn @@ -525,7 +525,7 @@ func makepartialcall(dot *ir.Node, t0 *types.Type, meth *types.Sym) *ir.Node { func partialCallType(n *ir.Node) *types.Type { t := tostruct([]*ir.Node{ namedfield("F", types.Types[types.TUINTPTR]), - namedfield("R", n.Left.Type), + namedfield("R", n.Left().Type()), }) t.SetNoalg(true) return t @@ -539,13 +539,13 @@ func walkpartialcall(n *ir.Node, init *ir.Nodes) *ir.Node { // // Like walkclosure above. - if n.Left.Type.IsInterface() { + if n.Left().Type().IsInterface() { // Trigger panic for method on nil interface now. // Otherwise it happens in the wrapper and is confusing. - n.Left = cheapexpr(n.Left, init) - n.Left = walkexpr(n.Left, nil) + n.SetLeft(cheapexpr(n.Left(), init)) + n.SetLeft(walkexpr(n.Left(), nil)) - tab := ir.Nod(ir.OITAB, n.Left, nil) + tab := ir.Nod(ir.OITAB, n.Left(), nil) tab = typecheck(tab, ctxExpr) c := ir.Nod(ir.OCHECKNIL, tab, nil) @@ -556,21 +556,21 @@ func walkpartialcall(n *ir.Node, init *ir.Nodes) *ir.Node { typ := partialCallType(n) clos := ir.Nod(ir.OCOMPLIT, nil, typenod(typ)) - clos.Esc = n.Esc - clos.List.Set2(ir.Nod(ir.OCFUNC, n.Func.Nname, nil), n.Left) + clos.SetEsc(n.Esc()) + clos.PtrList().Set2(ir.Nod(ir.OCFUNC, n.Func().Nname, nil), n.Left()) clos = ir.Nod(ir.OADDR, clos, nil) - clos.Esc = n.Esc + clos.SetEsc(n.Esc()) // Force type conversion from *struct to the func type. - clos = convnop(clos, n.Type) + clos = convnop(clos, n.Type()) // non-escaping temp to use, if any. if x := prealloc[n]; x != nil { - if !types.Identical(typ, x.Type) { + if !types.Identical(typ, x.Type()) { panic("partial call type does not match order's assigned type") } - clos.Left.Right = x + clos.Left().SetRight(x) delete(prealloc, n) } @@ -580,14 +580,14 @@ func walkpartialcall(n *ir.Node, init *ir.Nodes) *ir.Node { // callpartMethod returns the *types.Field representing the method // referenced by method value n. func callpartMethod(n *ir.Node) *types.Field { - if n.Op != ir.OCALLPART { + if n.Op() != ir.OCALLPART { base.Fatalf("expected OCALLPART, got %v", n) } // TODO(mdempsky): Optimize this. If necessary, // makepartialcall could save m for us somewhere. var m *types.Field - if lookdot0(n.Right.Sym, n.Left.Type, &m, false) != 1 { + if lookdot0(n.Right().Sym(), n.Left().Type(), &m, false) != 1 { base.Fatalf("failed to find field for OCALLPART") } diff --git a/src/cmd/compile/internal/gc/const.go b/src/cmd/compile/internal/gc/const.go index a557e20d46..27e54b46c8 100644 --- a/src/cmd/compile/internal/gc/const.go +++ b/src/cmd/compile/internal/gc/const.go @@ -106,30 +106,30 @@ func convlit1(n *ir.Node, t *types.Type, explicit bool, context func() string) * base.Fatalf("bad conversion to untyped: %v", t) } - if n == nil || n.Type == nil { + if n == nil || n.Type() == nil { // Allow sloppy callers. return n } - if !n.Type.IsUntyped() { + if !n.Type().IsUntyped() { // Already typed; nothing to do. return n } - if n.Op == ir.OLITERAL || n.Op == ir.ONIL { + if n.Op() == ir.OLITERAL || n.Op() == ir.ONIL { // Can't always set n.Type directly on OLITERAL nodes. // See discussion on CL 20813. n = n.RawCopy() } // Nil is technically not a constant, so handle it specially. - if n.Type.Etype == types.TNIL { - if n.Op != ir.ONIL { - base.Fatalf("unexpected op: %v (%v)", n, n.Op) + if n.Type().Etype == types.TNIL { + if n.Op() != ir.ONIL { + base.Fatalf("unexpected op: %v (%v)", n, n.Op()) } if t == nil { base.Errorf("use of untyped nil") n.SetDiag(true) - n.Type = nil + n.SetType(nil) return n } @@ -138,15 +138,15 @@ func convlit1(n *ir.Node, t *types.Type, explicit bool, context func() string) * return n } - n.Type = t + n.SetType(t) return n } if t == nil || !ir.OKForConst[t.Etype] { - t = defaultType(n.Type) + t = defaultType(n.Type()) } - switch n.Op { + switch n.Op() { default: base.Fatalf("unexpected untyped expression: %v", n) @@ -155,60 +155,60 @@ func convlit1(n *ir.Node, t *types.Type, explicit bool, context func() string) * if v.Kind() == constant.Unknown { break } - n.Type = t + n.SetType(t) n.SetVal(v) return n case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.OREAL, ir.OIMAG: - ot := operandType(n.Op, t) + ot := operandType(n.Op(), t) if ot == nil { n = defaultlit(n, nil) break } - n.Left = convlit(n.Left, ot) - if n.Left.Type == nil { - n.Type = nil + n.SetLeft(convlit(n.Left(), ot)) + if n.Left().Type() == nil { + n.SetType(nil) return n } - n.Type = t + n.SetType(t) return n case ir.OADD, ir.OSUB, ir.OMUL, ir.ODIV, ir.OMOD, ir.OOR, ir.OXOR, ir.OAND, ir.OANDNOT, ir.OOROR, ir.OANDAND, ir.OCOMPLEX: - ot := operandType(n.Op, t) + ot := operandType(n.Op(), t) if ot == nil { n = defaultlit(n, nil) break } - n.Left = convlit(n.Left, ot) - n.Right = convlit(n.Right, ot) - if n.Left.Type == nil || n.Right.Type == nil { - n.Type = nil + n.SetLeft(convlit(n.Left(), ot)) + n.SetRight(convlit(n.Right(), ot)) + if n.Left().Type() == nil || n.Right().Type() == nil { + n.SetType(nil) return n } - if !types.Identical(n.Left.Type, n.Right.Type) { - base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, n.Left.Type, n.Right.Type) - n.Type = nil + if !types.Identical(n.Left().Type(), n.Right().Type()) { + base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, n.Left().Type(), n.Right().Type()) + n.SetType(nil) return n } - n.Type = t + n.SetType(t) return n case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE: if !t.IsBoolean() { break } - n.Type = t + n.SetType(t) return n case ir.OLSH, ir.ORSH: - n.Left = convlit1(n.Left, t, explicit, nil) - n.Type = n.Left.Type - if n.Type != nil && !n.Type.IsInteger() { - base.Errorf("invalid operation: %v (shift of type %v)", n, n.Type) - n.Type = nil + n.SetLeft(convlit1(n.Left(), t, explicit, nil)) + n.SetType(n.Left().Type()) + if n.Type() != nil && !n.Type().IsInteger() { + base.Errorf("invalid operation: %v (shift of type %v)", n, n.Type()) + n.SetType(nil) } return n } @@ -225,7 +225,7 @@ func convlit1(n *ir.Node, t *types.Type, explicit bool, context func() string) * } n.SetDiag(true) } - n.Type = nil + n.SetType(nil) return n } @@ -439,75 +439,75 @@ var tokenForOp = [...]token.Token{ // Otherwise, evalConst returns a new OLITERAL with the same value as n, // and with .Orig pointing back to n. func evalConst(n *ir.Node) *ir.Node { - nl, nr := n.Left, n.Right + nl, nr := n.Left(), n.Right() // Pick off just the opcodes that can be constant evaluated. - switch op := n.Op; op { + switch op := n.Op(); op { case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT: - if nl.Op == ir.OLITERAL { + if nl.Op() == ir.OLITERAL { var prec uint - if n.Type.IsUnsigned() { - prec = uint(n.Type.Size() * 8) + if n.Type().IsUnsigned() { + prec = uint(n.Type().Size() * 8) } return origConst(n, constant.UnaryOp(tokenForOp[op], nl.Val(), prec)) } case ir.OADD, ir.OSUB, ir.OMUL, ir.ODIV, ir.OMOD, ir.OOR, ir.OXOR, ir.OAND, ir.OANDNOT, ir.OOROR, ir.OANDAND: - if nl.Op == ir.OLITERAL && nr.Op == ir.OLITERAL { + if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL { rval := nr.Val() // check for divisor underflow in complex division (see issue 20227) - if op == ir.ODIV && n.Type.IsComplex() && constant.Sign(square(constant.Real(rval))) == 0 && constant.Sign(square(constant.Imag(rval))) == 0 { + if op == ir.ODIV && n.Type().IsComplex() && constant.Sign(square(constant.Real(rval))) == 0 && constant.Sign(square(constant.Imag(rval))) == 0 { base.Errorf("complex division by zero") - n.Type = nil + n.SetType(nil) return n } if (op == ir.ODIV || op == ir.OMOD) && constant.Sign(rval) == 0 { base.Errorf("division by zero") - n.Type = nil + n.SetType(nil) return n } tok := tokenForOp[op] - if op == ir.ODIV && n.Type.IsInteger() { + if op == ir.ODIV && n.Type().IsInteger() { tok = token.QUO_ASSIGN // integer division } return origConst(n, constant.BinaryOp(nl.Val(), tok, rval)) } case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE: - if nl.Op == ir.OLITERAL && nr.Op == ir.OLITERAL { + if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL { return origBoolConst(n, constant.Compare(nl.Val(), tokenForOp[op], nr.Val())) } case ir.OLSH, ir.ORSH: - if nl.Op == ir.OLITERAL && nr.Op == ir.OLITERAL { + if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL { // shiftBound from go/types; "so we can express smallestFloat64" const shiftBound = 1023 - 1 + 52 s, ok := constant.Uint64Val(nr.Val()) if !ok || s > shiftBound { base.Errorf("invalid shift count %v", nr) - n.Type = nil + n.SetType(nil) break } return origConst(n, constant.Shift(toint(nl.Val()), tokenForOp[op], uint(s))) } case ir.OCONV, ir.ORUNESTR: - if ir.OKForConst[n.Type.Etype] && nl.Op == ir.OLITERAL { - return origConst(n, convertVal(nl.Val(), n.Type, true)) + if ir.OKForConst[n.Type().Etype] && nl.Op() == ir.OLITERAL { + return origConst(n, convertVal(nl.Val(), n.Type(), true)) } case ir.OCONVNOP: - if ir.OKForConst[n.Type.Etype] && nl.Op == ir.OLITERAL { + if ir.OKForConst[n.Type().Etype] && nl.Op() == ir.OLITERAL { // set so n.Orig gets OCONV instead of OCONVNOP - n.Op = ir.OCONV + n.SetOp(ir.OCONV) return origConst(n, nl.Val()) } case ir.OADDSTR: // Merge adjacent constants in the argument list. - s := n.List.Slice() + s := n.List().Slice() need := 0 for i := 0; i < len(s); i++ { if i == 0 || !ir.IsConst(s[i-1], constant.String) || !ir.IsConst(s[i], constant.String) { @@ -537,7 +537,7 @@ func evalConst(n *ir.Node) *ir.Node { } nl := origConst(s[i], constant.MakeString(strings.Join(strs, ""))) - nl.Orig = nl // it's bigger than just s[i] + nl.SetOrig(nl) // it's bigger than just s[i] newList = append(newList, nl) i = i2 - 1 } else { @@ -546,18 +546,18 @@ func evalConst(n *ir.Node) *ir.Node { } n = ir.Copy(n) - n.List.Set(newList) + n.PtrList().Set(newList) return n case ir.OCAP, ir.OLEN: - switch nl.Type.Etype { + switch nl.Type().Etype { case types.TSTRING: if ir.IsConst(nl, constant.String) { return origIntConst(n, int64(len(nl.StringVal()))) } case types.TARRAY: if !hascallchan(nl) { - return origIntConst(n, nl.Type.NumElem()) + return origIntConst(n, nl.Type().NumElem()) } } @@ -565,17 +565,17 @@ func evalConst(n *ir.Node) *ir.Node { return origIntConst(n, evalunsafe(n)) case ir.OREAL: - if nl.Op == ir.OLITERAL { + if nl.Op() == ir.OLITERAL { return origConst(n, constant.Real(nl.Val())) } case ir.OIMAG: - if nl.Op == ir.OLITERAL { + if nl.Op() == ir.OLITERAL { return origConst(n, constant.Imag(nl.Val())) } case ir.OCOMPLEX: - if nl.Op == ir.OLITERAL && nr.Op == ir.OLITERAL { + if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL { return origConst(n, makeComplex(nl.Val(), nr.Val())) } } @@ -621,7 +621,7 @@ var overflowNames = [...]string{ // origConst returns an OLITERAL with orig n and value v. func origConst(n *ir.Node, v constant.Value) *ir.Node { lno := setlineno(n) - v = convertVal(v, n.Type, false) + v = convertVal(v, n.Type(), false) base.Pos = lno switch v.Kind() { @@ -631,19 +631,19 @@ func origConst(n *ir.Node, v constant.Value) *ir.Node { } fallthrough case constant.Unknown: - what := overflowNames[n.Op] + what := overflowNames[n.Op()] if what == "" { - base.Fatalf("unexpected overflow: %v", n.Op) + base.Fatalf("unexpected overflow: %v", n.Op()) } - base.ErrorfAt(n.Pos, "constant %v overflow", what) - n.Type = nil + base.ErrorfAt(n.Pos(), "constant %v overflow", what) + n.SetType(nil) return n } orig := n - n = ir.NodAt(orig.Pos, ir.OLITERAL, nil, nil) - n.Orig = orig - n.Type = orig.Type + n = ir.NodAt(orig.Pos(), ir.OLITERAL, nil, nil) + n.SetOrig(orig) + n.SetType(orig.Type()) n.SetVal(v) return n } @@ -663,16 +663,16 @@ func origIntConst(n *ir.Node, v int64) *ir.Node { // The results of defaultlit2 MUST be assigned back to l and r, e.g. // n.Left, n.Right = defaultlit2(n.Left, n.Right, force) func defaultlit2(l *ir.Node, r *ir.Node, force bool) (*ir.Node, *ir.Node) { - if l.Type == nil || r.Type == nil { + if l.Type() == nil || r.Type() == nil { return l, r } - if !l.Type.IsUntyped() { - r = convlit(r, l.Type) + if !l.Type().IsUntyped() { + r = convlit(r, l.Type()) return l, r } - if !r.Type.IsUntyped() { - l = convlit(l, r.Type) + if !r.Type().IsUntyped() { + l = convlit(l, r.Type()) return l, r } @@ -681,17 +681,17 @@ func defaultlit2(l *ir.Node, r *ir.Node, force bool) (*ir.Node, *ir.Node) { } // Can't mix bool with non-bool, string with non-string, or nil with anything (untyped). - if l.Type.IsBoolean() != r.Type.IsBoolean() { + if l.Type().IsBoolean() != r.Type().IsBoolean() { return l, r } - if l.Type.IsString() != r.Type.IsString() { + if l.Type().IsString() != r.Type().IsString() { return l, r } if ir.IsNil(l) || ir.IsNil(r) { return l, r } - t := defaultType(mixUntyped(l.Type, r.Type)) + t := defaultType(mixUntyped(l.Type(), r.Type())) l = convlit(l, t) r = convlit(r, t) return l, r @@ -748,7 +748,7 @@ func defaultType(t *types.Type) *types.Type { } func smallintconst(n *ir.Node) bool { - if n.Op == ir.OLITERAL { + if n.Op() == ir.OLITERAL { v, ok := constant.Int64Val(n.Val()) return ok && int64(int32(v)) == v } @@ -761,10 +761,10 @@ func smallintconst(n *ir.Node) bool { // integer, or negative, it returns -1. If n is too large, it // returns -2. func indexconst(n *ir.Node) int64 { - if n.Op != ir.OLITERAL { + if n.Op() != ir.OLITERAL { return -1 } - if !n.Type.IsInteger() && n.Type.Etype != types.TIDEAL { + if !n.Type().IsInteger() && n.Type().Etype != types.TIDEAL { return -1 } @@ -784,14 +784,14 @@ func indexconst(n *ir.Node) int64 { // Expressions derived from nil, like string([]byte(nil)), while they // may be known at compile time, are not Go language constants. func isGoConst(n *ir.Node) bool { - return n.Op == ir.OLITERAL + return n.Op() == ir.OLITERAL } func hascallchan(n *ir.Node) bool { if n == nil { return false } - switch n.Op { + switch n.Op() { case ir.OAPPEND, ir.OCALL, ir.OCALLFUNC, @@ -815,15 +815,15 @@ func hascallchan(n *ir.Node) bool { return true } - if hascallchan(n.Left) || hascallchan(n.Right) { + if hascallchan(n.Left()) || hascallchan(n.Right()) { return true } - for _, n1 := range n.List.Slice() { + for _, n1 := range n.List().Slice() { if hascallchan(n1) { return true } } - for _, n2 := range n.Rlist.Slice() { + for _, n2 := range n.Rlist().Slice() { if hascallchan(n2) { return true } @@ -852,14 +852,14 @@ type constSetKey struct { // // n must not be an untyped constant. func (s *constSet) add(pos src.XPos, n *ir.Node, what, where string) { - if n.Op == ir.OCONVIFACE && n.Implicit() { - n = n.Left + if n.Op() == ir.OCONVIFACE && n.Implicit() { + n = n.Left() } if !isGoConst(n) { return } - if n.Type.IsUntyped() { + if n.Type().IsUntyped() { base.Fatalf("%v is untyped", n) } @@ -878,7 +878,7 @@ func (s *constSet) add(pos src.XPos, n *ir.Node, what, where string) { // #21866 by treating all type aliases like byte/uint8 and // rune/int32. - typ := n.Type + typ := n.Type() switch typ { case types.Bytetype: typ = types.Types[types.TUINT8] @@ -888,7 +888,7 @@ func (s *constSet) add(pos src.XPos, n *ir.Node, what, where string) { k := constSetKey{typ, ir.ConstValue(n)} if hasUniquePos(n) { - pos = n.Pos + pos = n.Pos() } if s.m == nil { diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index 6fee872fd2..8b3274890f 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -64,78 +64,78 @@ func declare(n *ir.Node, ctxt ir.Class) { return } - if n.Name == nil { + if n.Name() == nil { // named OLITERAL needs Name; most OLITERALs don't. - n.Name = new(ir.Name) + n.SetName(new(ir.Name)) } - s := n.Sym + s := n.Sym() // kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later. if !inimport && !typecheckok && s.Pkg != ir.LocalPkg { - base.ErrorfAt(n.Pos, "cannot declare name %v", s) + base.ErrorfAt(n.Pos(), "cannot declare name %v", s) } gen := 0 if ctxt == ir.PEXTERN { if s.Name == "init" { - base.ErrorfAt(n.Pos, "cannot declare init - must be func") + base.ErrorfAt(n.Pos(), "cannot declare init - must be func") } if s.Name == "main" && s.Pkg.Name == "main" { - base.ErrorfAt(n.Pos, "cannot declare main - must be func") + base.ErrorfAt(n.Pos(), "cannot declare main - must be func") } externdcl = append(externdcl, n) } else { if Curfn == nil && ctxt == ir.PAUTO { - base.Pos = n.Pos + base.Pos = n.Pos() base.Fatalf("automatic outside function") } if Curfn != nil && ctxt != ir.PFUNC { - Curfn.Func.Dcl = append(Curfn.Func.Dcl, n) + Curfn.Func().Dcl = append(Curfn.Func().Dcl, n) } - if n.Op == ir.OTYPE { + if n.Op() == ir.OTYPE { declare_typegen++ gen = declare_typegen - } else if n.Op == ir.ONAME && ctxt == ir.PAUTO && !strings.Contains(s.Name, "·") { + } else if n.Op() == ir.ONAME && ctxt == ir.PAUTO && !strings.Contains(s.Name, "·") { vargen++ gen = vargen } types.Pushdcl(s) - n.Name.Curfn = Curfn + n.Name().Curfn = Curfn } if ctxt == ir.PAUTO { - n.Xoffset = 0 + n.SetOffset(0) } if s.Block == types.Block { // functype will print errors about duplicate function arguments. // Don't repeat the error here. if ctxt != ir.PPARAM && ctxt != ir.PPARAMOUT { - redeclare(n.Pos, s, "in this block") + redeclare(n.Pos(), s, "in this block") } } s.Block = types.Block s.Lastlineno = base.Pos s.Def = ir.AsTypesNode(n) - n.Name.Vargen = int32(gen) + n.Name().Vargen = int32(gen) n.SetClass(ctxt) if ctxt == ir.PFUNC { - n.Sym.SetFunc(true) + n.Sym().SetFunc(true) } autoexport(n, ctxt) } func addvar(n *ir.Node, t *types.Type, ctxt ir.Class) { - if n == nil || n.Sym == nil || (n.Op != ir.ONAME && n.Op != ir.ONONAME) || t == nil { + if n == nil || n.Sym() == nil || (n.Op() != ir.ONAME && n.Op() != ir.ONONAME) || t == nil { base.Fatalf("addvar: n=%v t=%v nil", n, t) } - n.Op = ir.ONAME + n.SetOp(ir.ONAME) declare(n, ctxt) - n.Type = t + n.SetType(t) } // declare variables from grammar @@ -147,13 +147,13 @@ func variter(vl []*ir.Node, t *ir.Node, el []*ir.Node) []*ir.Node { if len(el) == 1 && len(vl) > 1 { e := el[0] as2 := ir.Nod(ir.OAS2, nil, nil) - as2.List.Set(vl) - as2.Rlist.Set1(e) + as2.PtrList().Set(vl) + as2.PtrRlist().Set1(e) for _, v := range vl { - v.Op = ir.ONAME + v.SetOp(ir.ONAME) declare(v, dclcontext) - v.Name.Param.Ntype = t - v.Name.Defn = as2 + v.Name().Param.Ntype = t + v.Name().Defn = as2 if Curfn != nil { init = append(init, ir.Nod(ir.ODCL, v, nil)) } @@ -174,9 +174,9 @@ func variter(vl []*ir.Node, t *ir.Node, el []*ir.Node) []*ir.Node { el = el[1:] } - v.Op = ir.ONAME + v.SetOp(ir.ONAME) declare(v, dclcontext) - v.Name.Param.Ntype = t + v.Name().Param.Ntype = t if e != nil || Curfn != nil || ir.IsBlank(v) { if Curfn != nil { @@ -184,8 +184,8 @@ func variter(vl []*ir.Node, t *ir.Node, el []*ir.Node) []*ir.Node { } e = ir.Nod(ir.OAS, v, e) init = append(init, e) - if e.Right != nil { - v.Name.Defn = e + if e.Right() != nil { + v.Name().Defn = e } } } @@ -202,8 +202,8 @@ func newnoname(s *types.Sym) *ir.Node { base.Fatalf("newnoname nil") } n := ir.Nod(ir.ONONAME, nil, nil) - n.Sym = s - n.Xoffset = 0 + n.SetSym(s) + n.SetOffset(0) return n } @@ -213,7 +213,7 @@ func newfuncnamel(pos src.XPos, s *types.Sym, fn *ir.Func) *ir.Node { base.Fatalf("newfuncnamel - already have name") } n := ir.NewNameAt(pos, s) - n.Func = fn + n.SetFunc(fn) fn.Nname = n return n } @@ -222,7 +222,7 @@ func newfuncnamel(pos src.XPos, s *types.Sym, fn *ir.Func) *ir.Node { // being declared. func dclname(s *types.Sym) *ir.Node { n := NewName(s) - n.Op = ir.ONONAME // caller will correct it + n.SetOp(ir.ONONAME) // caller will correct it return n } @@ -234,10 +234,10 @@ func typenodl(pos src.XPos, t *types.Type) *ir.Node { // if we copied another type with *t = *u // then t->nod might be out of date, so // check t->nod->type too - if ir.AsNode(t.Nod) == nil || ir.AsNode(t.Nod).Type != t { + if ir.AsNode(t.Nod) == nil || ir.AsNode(t.Nod).Type() != t { t.Nod = ir.AsTypesNode(ir.NodAt(pos, ir.OTYPE, nil, nil)) - ir.AsNode(t.Nod).Type = t - ir.AsNode(t.Nod).Sym = t.Sym + ir.AsNode(t.Nod).SetType(t) + ir.AsNode(t.Nod).SetSym(t.Sym) } return ir.AsNode(t.Nod) @@ -253,7 +253,7 @@ func namedfield(s string, typ *types.Type) *ir.Node { func symfield(s *types.Sym, typ *types.Type) *ir.Node { n := nodSym(ir.ODCLFIELD, nil, s) - n.Type = typ + n.SetType(typ) return n } @@ -270,28 +270,28 @@ func oldname(s *types.Sym) *ir.Node { return newnoname(s) } - if Curfn != nil && n.Op == ir.ONAME && n.Name.Curfn != nil && n.Name.Curfn != Curfn { + if Curfn != nil && n.Op() == ir.ONAME && n.Name().Curfn != nil && n.Name().Curfn != Curfn { // Inner func is referring to var in outer func. // // TODO(rsc): If there is an outer variable x and we // are parsing x := 5 inside the closure, until we get to // the := it looks like a reference to the outer x so we'll // make x a closure variable unnecessarily. - c := n.Name.Param.Innermost - if c == nil || c.Name.Curfn != Curfn { + c := n.Name().Param.Innermost + if c == nil || c.Name().Curfn != Curfn { // Do not have a closure var for the active closure yet; make one. c = NewName(s) c.SetClass(ir.PAUTOHEAP) - c.Name.SetIsClosureVar(true) + c.Name().SetIsClosureVar(true) c.SetIsDDD(n.IsDDD()) - c.Name.Defn = n + c.Name().Defn = n // Link into list of active closure variables. // Popped from list in func funcLit. - c.Name.Param.Outer = n.Name.Param.Innermost - n.Name.Param.Innermost = c + c.Name().Param.Outer = n.Name().Param.Innermost + n.Name().Param.Innermost = c - Curfn.Func.ClosureVars.Append(c) + Curfn.Func().ClosureVars.Append(c) } // return ref to closure var, not original @@ -313,13 +313,13 @@ func importName(sym *types.Sym) *ir.Node { // := declarations func colasname(n *ir.Node) bool { - switch n.Op { + switch n.Op() { case ir.ONAME, ir.ONONAME, ir.OPACK, ir.OTYPE, ir.OLITERAL: - return n.Sym != nil + return n.Sym() != nil } return false @@ -327,8 +327,8 @@ func colasname(n *ir.Node) bool { func colasdefn(left []*ir.Node, defn *ir.Node) { for _, n := range left { - if n.Sym != nil { - n.Sym.SetUniq(true) + if n.Sym() != nil { + n.Sym().SetUniq(true) } } @@ -338,44 +338,44 @@ func colasdefn(left []*ir.Node, defn *ir.Node) { continue } if !colasname(n) { - base.ErrorfAt(defn.Pos, "non-name %v on left side of :=", n) + base.ErrorfAt(defn.Pos(), "non-name %v on left side of :=", n) nerr++ continue } - if !n.Sym.Uniq() { - base.ErrorfAt(defn.Pos, "%v repeated on left side of :=", n.Sym) + if !n.Sym().Uniq() { + base.ErrorfAt(defn.Pos(), "%v repeated on left side of :=", n.Sym()) n.SetDiag(true) nerr++ continue } - n.Sym.SetUniq(false) - if n.Sym.Block == types.Block { + n.Sym().SetUniq(false) + if n.Sym().Block == types.Block { continue } nnew++ - n = NewName(n.Sym) + n = NewName(n.Sym()) declare(n, dclcontext) - n.Name.Defn = defn - defn.Ninit.Append(ir.Nod(ir.ODCL, n, nil)) + n.Name().Defn = defn + defn.PtrInit().Append(ir.Nod(ir.ODCL, n, nil)) left[i] = n } if nnew == 0 && nerr == 0 { - base.ErrorfAt(defn.Pos, "no new variables on left side of :=") + base.ErrorfAt(defn.Pos(), "no new variables on left side of :=") } } // declare the arguments in an // interface field declaration. func ifacedcl(n *ir.Node) { - if n.Op != ir.ODCLFIELD || n.Left == nil { + if n.Op() != ir.ODCLFIELD || n.Left() == nil { base.Fatalf("ifacedcl") } - if n.Sym.IsBlank() { + if n.Sym().IsBlank() { base.Errorf("methods must have a unique non-blank name") } } @@ -392,16 +392,16 @@ func funchdr(n *ir.Node) { types.Markdcl() - if n.Func.Nname != nil && n.Func.Nname.Name.Param.Ntype != nil { - funcargs(n.Func.Nname.Name.Param.Ntype) + if n.Func().Nname != nil && n.Func().Nname.Name().Param.Ntype != nil { + funcargs(n.Func().Nname.Name().Param.Ntype) } else { - funcargs2(n.Type) + funcargs2(n.Type()) } } func funcargs(nt *ir.Node) { - if nt.Op != ir.OTFUNC { - base.Fatalf("funcargs %v", nt.Op) + if nt.Op() != ir.OTFUNC { + base.Fatalf("funcargs %v", nt.Op()) } // re-start the variable generation number @@ -411,13 +411,13 @@ func funcargs(nt *ir.Node) { // TODO(mdempsky): This is ugly, and only necessary because // esc.go uses Vargen to figure out result parameters' index // within the result tuple. - vargen = nt.Rlist.Len() + vargen = nt.Rlist().Len() // declare the receiver and in arguments. - if nt.Left != nil { - funcarg(nt.Left, ir.PPARAM) + if nt.Left() != nil { + funcarg(nt.Left(), ir.PPARAM) } - for _, n := range nt.List.Slice() { + for _, n := range nt.List().Slice() { funcarg(n, ir.PPARAM) } @@ -425,21 +425,21 @@ func funcargs(nt *ir.Node) { vargen = 0 // declare the out arguments. - gen := nt.List.Len() - for _, n := range nt.Rlist.Slice() { - if n.Sym == nil { + gen := nt.List().Len() + for _, n := range nt.Rlist().Slice() { + if n.Sym() == nil { // Name so that escape analysis can track it. ~r stands for 'result'. - n.Sym = lookupN("~r", gen) + n.SetSym(lookupN("~r", gen)) gen++ } - if n.Sym.IsBlank() { + if n.Sym().IsBlank() { // Give it a name so we can assign to it during return. ~b stands for 'blank'. // The name must be different from ~r above because if you have // func f() (_ int) // func g() int // f is allowed to use a plain 'return' with no arguments, while g is not. // So the two cases must be distinguished. - n.Sym = lookupN("~b", gen) + n.SetSym(lookupN("~b", gen)) gen++ } @@ -450,20 +450,20 @@ func funcargs(nt *ir.Node) { } func funcarg(n *ir.Node, ctxt ir.Class) { - if n.Op != ir.ODCLFIELD { - base.Fatalf("funcarg %v", n.Op) + if n.Op() != ir.ODCLFIELD { + base.Fatalf("funcarg %v", n.Op()) } - if n.Sym == nil { + if n.Sym() == nil { return } - n.Right = ir.NewNameAt(n.Pos, n.Sym) - n.Right.Name.Param.Ntype = n.Left - n.Right.SetIsDDD(n.IsDDD()) - declare(n.Right, ctxt) + n.SetRight(ir.NewNameAt(n.Pos(), n.Sym())) + n.Right().Name().Param.Ntype = n.Left() + n.Right().SetIsDDD(n.IsDDD()) + declare(n.Right(), ctxt) vargen++ - n.Right.Name.Vargen = int32(vargen) + n.Right().Name().Vargen = int32(vargen) } // Same as funcargs, except run over an already constructed TFUNC. @@ -491,7 +491,7 @@ func funcarg2(f *types.Field, ctxt ir.Class) { } n := ir.NewNameAt(f.Pos, f.Sym) f.Nname = ir.AsTypesNode(n) - n.Type = f.Type + n.SetType(f.Type) n.SetIsDDD(f.IsDDD()) declare(n, ctxt) } @@ -537,21 +537,21 @@ func checkembeddedtype(t *types.Type) { func structfield(n *ir.Node) *types.Field { lno := base.Pos - base.Pos = n.Pos + base.Pos = n.Pos() - if n.Op != ir.ODCLFIELD { + if n.Op() != ir.ODCLFIELD { base.Fatalf("structfield: oops %v\n", n) } - if n.Left != nil { - n.Left = typecheck(n.Left, ctxType) - n.Type = n.Left.Type - n.Left = nil + if n.Left() != nil { + n.SetLeft(typecheck(n.Left(), ctxType)) + n.SetType(n.Left().Type()) + n.SetLeft(nil) } - f := types.NewField(n.Pos, n.Sym, n.Type) + f := types.NewField(n.Pos(), n.Sym(), n.Type()) if n.Embedded() { - checkembeddedtype(n.Type) + checkembeddedtype(n.Type()) f.Embedded = 1 } if n.HasVal() { @@ -612,9 +612,9 @@ func tofunargs(l []*ir.Node, funarg types.Funarg) *types.Type { for i, n := range l { f := structfield(n) f.SetIsDDD(n.IsDDD()) - if n.Right != nil { - n.Right.Type = f.Type - f.Nname = ir.AsTypesNode(n.Right) + if n.Right() != nil { + n.Right().SetType(f.Type) + f.Nname = ir.AsTypesNode(n.Right()) } if f.Broke() { t.SetBroke(true) @@ -634,9 +634,9 @@ func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type { func interfacefield(n *ir.Node) *types.Field { lno := base.Pos - base.Pos = n.Pos + base.Pos = n.Pos() - if n.Op != ir.ODCLFIELD { + if n.Op() != ir.ODCLFIELD { base.Fatalf("interfacefield: oops %v\n", n) } @@ -649,13 +649,13 @@ func interfacefield(n *ir.Node) *types.Field { // If Sym != nil, then Sym is MethodName and Left is Signature. // Otherwise, Left is InterfaceTypeName. - if n.Left != nil { - n.Left = typecheck(n.Left, ctxType) - n.Type = n.Left.Type - n.Left = nil + if n.Left() != nil { + n.SetLeft(typecheck(n.Left(), ctxType)) + n.SetType(n.Left().Type()) + n.SetLeft(nil) } - f := types.NewField(n.Pos, n.Sym, n.Type) + f := types.NewField(n.Pos(), n.Sym(), n.Type()) base.Pos = lno return f @@ -872,7 +872,7 @@ func addmethod(n *ir.Node, msym *types.Sym, t *types.Type, local, nointerface bo } f := types.NewField(base.Pos, msym, t) - f.Nname = ir.AsTypesNode(n.Func.Nname) + f.Nname = ir.AsTypesNode(n.Func().Nname) f.SetNointerface(nointerface) mt.Methods().Append(f) @@ -936,26 +936,26 @@ func makefuncsym(s *types.Sym) { // setNodeNameFunc marks a node as a function. func setNodeNameFunc(n *ir.Node) { - if n.Op != ir.ONAME || n.Class() != ir.Pxxx { + if n.Op() != ir.ONAME || n.Class() != ir.Pxxx { base.Fatalf("expected ONAME/Pxxx node, got %v", n) } n.SetClass(ir.PFUNC) - n.Sym.SetFunc(true) + n.Sym().SetFunc(true) } func dclfunc(sym *types.Sym, tfn *ir.Node) *ir.Node { - if tfn.Op != ir.OTFUNC { + if tfn.Op() != ir.OTFUNC { base.Fatalf("expected OTFUNC node, got %v", tfn) } fn := ir.Nod(ir.ODCLFUNC, nil, nil) - fn.Func.Nname = newfuncnamel(base.Pos, sym, fn.Func) - fn.Func.Nname.Name.Defn = fn - fn.Func.Nname.Name.Param.Ntype = tfn - setNodeNameFunc(fn.Func.Nname) + fn.Func().Nname = newfuncnamel(base.Pos, sym, fn.Func()) + fn.Func().Nname.Name().Defn = fn + fn.Func().Nname.Name().Param.Ntype = tfn + setNodeNameFunc(fn.Func().Nname) funchdr(fn) - fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, ctxType) + fn.Func().Nname.Name().Param.Ntype = typecheck(fn.Func().Nname.Name().Param.Ntype, ctxType) return fn } @@ -987,7 +987,7 @@ func newNowritebarrierrecChecker() *nowritebarrierrecChecker { // directly. This has to happen before transformclosure since // it's a lot harder to work out the argument after. for _, n := range xtop { - if n.Op != ir.ODCLFUNC { + if n.Op() != ir.ODCLFUNC { continue } c.curfn = n @@ -998,31 +998,31 @@ func newNowritebarrierrecChecker() *nowritebarrierrecChecker { } func (c *nowritebarrierrecChecker) findExtraCalls(n *ir.Node) bool { - if n.Op != ir.OCALLFUNC { + if n.Op() != ir.OCALLFUNC { return true } - fn := n.Left - if fn == nil || fn.Op != ir.ONAME || fn.Class() != ir.PFUNC || fn.Name.Defn == nil { + fn := n.Left() + if fn == nil || fn.Op() != ir.ONAME || fn.Class() != ir.PFUNC || fn.Name().Defn == nil { return true } - if !isRuntimePkg(fn.Sym.Pkg) || fn.Sym.Name != "systemstack" { + if !isRuntimePkg(fn.Sym().Pkg) || fn.Sym().Name != "systemstack" { return true } var callee *ir.Node - arg := n.List.First() - switch arg.Op { + arg := n.List().First() + switch arg.Op() { case ir.ONAME: - callee = arg.Name.Defn + callee = arg.Name().Defn case ir.OCLOSURE: - callee = arg.Func.Decl + callee = arg.Func().Decl default: base.Fatalf("expected ONAME or OCLOSURE node, got %+v", arg) } - if callee.Op != ir.ODCLFUNC { + if callee.Op() != ir.ODCLFUNC { base.Fatalf("expected ODCLFUNC node, got %+v", callee) } - c.extraCalls[c.curfn] = append(c.extraCalls[c.curfn], nowritebarrierrecCall{callee, n.Pos}) + c.extraCalls[c.curfn] = append(c.extraCalls[c.curfn], nowritebarrierrecCall{callee, n.Pos()}) return true } @@ -1035,12 +1035,12 @@ func (c *nowritebarrierrecChecker) findExtraCalls(n *ir.Node) bool { // // This can be called concurrently for different from Nodes. func (c *nowritebarrierrecChecker) recordCall(from *ir.Node, to *obj.LSym, pos src.XPos) { - if from.Op != ir.ODCLFUNC { + if from.Op() != ir.ODCLFUNC { base.Fatalf("expected ODCLFUNC, got %v", from) } // We record this information on the *Func so this is // concurrent-safe. - fn := from.Func + fn := from.Func() if fn.NWBRCalls == nil { fn.NWBRCalls = new([]ir.SymAndPos) } @@ -1064,27 +1064,27 @@ func (c *nowritebarrierrecChecker) check() { var q ir.NodeQueue for _, n := range xtop { - if n.Op != ir.ODCLFUNC { + if n.Op() != ir.ODCLFUNC { continue } - symToFunc[n.Func.LSym] = n + symToFunc[n.Func().LSym] = n // Make nowritebarrierrec functions BFS roots. - if n.Func.Pragma&ir.Nowritebarrierrec != 0 { + if n.Func().Pragma&ir.Nowritebarrierrec != 0 { funcs[n] = nowritebarrierrecCall{} q.PushRight(n) } // Check go:nowritebarrier functions. - if n.Func.Pragma&ir.Nowritebarrier != 0 && n.Func.WBPos.IsKnown() { - base.ErrorfAt(n.Func.WBPos, "write barrier prohibited") + if n.Func().Pragma&ir.Nowritebarrier != 0 && n.Func().WBPos.IsKnown() { + base.ErrorfAt(n.Func().WBPos, "write barrier prohibited") } } // Perform a BFS of the call graph from all // go:nowritebarrierrec functions. enqueue := func(src, target *ir.Node, pos src.XPos) { - if target.Func.Pragma&ir.Yeswritebarrierrec != 0 { + if target.Func().Pragma&ir.Yeswritebarrierrec != 0 { // Don't flow into this function. return } @@ -1101,14 +1101,14 @@ func (c *nowritebarrierrecChecker) check() { fn := q.PopLeft() // Check fn. - if fn.Func.WBPos.IsKnown() { + if fn.Func().WBPos.IsKnown() { var err bytes.Buffer call := funcs[fn] for call.target != nil { - fmt.Fprintf(&err, "\n\t%v: called by %v", base.FmtPos(call.lineno), call.target.Func.Nname) + fmt.Fprintf(&err, "\n\t%v: called by %v", base.FmtPos(call.lineno), call.target.Func().Nname) call = funcs[call.target] } - base.ErrorfAt(fn.Func.WBPos, "write barrier prohibited by caller; %v%s", fn.Func.Nname, err.String()) + base.ErrorfAt(fn.Func().WBPos, "write barrier prohibited by caller; %v%s", fn.Func().Nname, err.String()) continue } @@ -1116,10 +1116,10 @@ func (c *nowritebarrierrecChecker) check() { for _, callee := range c.extraCalls[fn] { enqueue(fn, callee.target, callee.lineno) } - if fn.Func.NWBRCalls == nil { + if fn.Func().NWBRCalls == nil { continue } - for _, callee := range *fn.Func.NWBRCalls { + for _, callee := range *fn.Func().NWBRCalls { target := symToFunc[callee.Sym] if target != nil { enqueue(fn, target, callee.Pos) diff --git a/src/cmd/compile/internal/gc/dwinl.go b/src/cmd/compile/internal/gc/dwinl.go index 5da2871748..1e4e43caad 100644 --- a/src/cmd/compile/internal/gc/dwinl.go +++ b/src/cmd/compile/internal/gc/dwinl.go @@ -236,15 +236,15 @@ func makePreinlineDclMap(fnsym *obj.LSym) map[varPos]int { dcl := preInliningDcls(fnsym) m := make(map[varPos]int) for i, n := range dcl { - pos := base.Ctxt.InnermostPos(n.Pos) + pos := base.Ctxt.InnermostPos(n.Pos()) vp := varPos{ - DeclName: unversion(n.Sym.Name), + DeclName: unversion(n.Sym().Name), DeclFile: pos.RelFilename(), DeclLine: pos.RelLine(), DeclCol: pos.Col(), } if _, found := m[vp]; found { - base.Fatalf("child dcl collision on symbol %s within %v\n", n.Sym.Name, fnsym.Name) + base.Fatalf("child dcl collision on symbol %s within %v\n", n.Sym().Name, fnsym.Name) } m[vp] = i } diff --git a/src/cmd/compile/internal/gc/embed.go b/src/cmd/compile/internal/gc/embed.go index 636aa4a70e..d515696add 100644 --- a/src/cmd/compile/internal/gc/embed.go +++ b/src/cmd/compile/internal/gc/embed.go @@ -113,15 +113,15 @@ func varEmbed(p *noder, names []*ir.Node, typ *ir.Node, exprs []*ir.Node, embeds v := names[0] if dclcontext != ir.PEXTERN { numLocalEmbed++ - v = ir.NewNameAt(v.Pos, lookupN("embed.", numLocalEmbed)) - v.Sym.Def = ir.AsTypesNode(v) - v.Name.Param.Ntype = typ + v = ir.NewNameAt(v.Pos(), lookupN("embed.", numLocalEmbed)) + v.Sym().Def = ir.AsTypesNode(v) + v.Name().Param.Ntype = typ v.SetClass(ir.PEXTERN) externdcl = append(externdcl, v) exprs = []*ir.Node{v} } - v.Name.Param.SetEmbedFiles(list) + v.Name().Param.SetEmbedFiles(list) embedlist = append(embedlist, v) return exprs } @@ -131,17 +131,17 @@ func varEmbed(p *noder, names []*ir.Node, typ *ir.Node, exprs []*ir.Node, embeds // can't tell whether "string" and "byte" really mean "string" and "byte". // The result must be confirmed later, after type checking, using embedKind. func embedKindApprox(typ *ir.Node) int { - if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == ir.LocalPkg && base.Ctxt.Pkgpath == "embed")) { + if typ.Sym() != nil && typ.Sym().Name == "FS" && (typ.Sym().Pkg.Path == "embed" || (typ.Sym().Pkg == ir.LocalPkg && base.Ctxt.Pkgpath == "embed")) { return embedFiles } // These are not guaranteed to match only string and []byte - // maybe the local package has redefined one of those words. // But it's the best we can do now during the noder. // The stricter check happens later, in initEmbed calling embedKind. - if typ.Sym != nil && typ.Sym.Name == "string" && typ.Sym.Pkg == ir.LocalPkg { + if typ.Sym() != nil && typ.Sym().Name == "string" && typ.Sym().Pkg == ir.LocalPkg { return embedString } - if typ.Op == ir.OTARRAY && typ.Left == nil && typ.Right.Sym != nil && typ.Right.Sym.Name == "byte" && typ.Right.Sym.Pkg == ir.LocalPkg { + if typ.Op() == ir.OTARRAY && typ.Left() == nil && typ.Right().Sym() != nil && typ.Right().Sym().Name == "byte" && typ.Right().Sym().Pkg == ir.LocalPkg { return embedBytes } return embedUnknown @@ -193,18 +193,18 @@ func dumpembeds() { // initEmbed emits the init data for a //go:embed variable, // which is either a string, a []byte, or an embed.FS. func initEmbed(v *ir.Node) { - files := v.Name.Param.EmbedFiles() - switch kind := embedKind(v.Type); kind { + files := v.Name().Param.EmbedFiles() + switch kind := embedKind(v.Type()); kind { case embedUnknown: - base.ErrorfAt(v.Pos, "go:embed cannot apply to var of type %v", v.Type) + base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type()) case embedString, embedBytes: file := files[0] - fsym, size, err := fileStringSym(v.Pos, base.Flag.Cfg.Embed.Files[file], kind == embedString, nil) + fsym, size, err := fileStringSym(v.Pos(), base.Flag.Cfg.Embed.Files[file], kind == embedString, nil) if err != nil { - base.ErrorfAt(v.Pos, "embed %s: %v", file, err) + base.ErrorfAt(v.Pos(), "embed %s: %v", file, err) } - sym := v.Sym.Linksym() + sym := v.Sym().Linksym() off := 0 off = dsymptr(sym, off, fsym, 0) // data string off = duintptr(sym, off, uint64(size)) // len @@ -213,7 +213,7 @@ func initEmbed(v *ir.Node) { } case embedFiles: - slicedata := base.Ctxt.Lookup(`"".` + v.Sym.Name + `.files`) + slicedata := base.Ctxt.Lookup(`"".` + v.Sym().Name + `.files`) off := 0 // []files pointed at by Files off = dsymptr(slicedata, off, slicedata, 3*Widthptr) // []file, pointing just past slice @@ -228,7 +228,7 @@ func initEmbed(v *ir.Node) { const hashSize = 16 hash := make([]byte, hashSize) for _, file := range files { - off = dsymptr(slicedata, off, stringsym(v.Pos, file), 0) // file string + off = dsymptr(slicedata, off, stringsym(v.Pos(), file), 0) // file string off = duintptr(slicedata, off, uint64(len(file))) if strings.HasSuffix(file, "/") { // entry for directory - no data @@ -236,9 +236,9 @@ func initEmbed(v *ir.Node) { off = duintptr(slicedata, off, 0) off += hashSize } else { - fsym, size, err := fileStringSym(v.Pos, base.Flag.Cfg.Embed.Files[file], true, hash) + fsym, size, err := fileStringSym(v.Pos(), base.Flag.Cfg.Embed.Files[file], true, hash) if err != nil { - base.ErrorfAt(v.Pos, "embed %s: %v", file, err) + base.ErrorfAt(v.Pos(), "embed %s: %v", file, err) } off = dsymptr(slicedata, off, fsym, 0) // data string off = duintptr(slicedata, off, uint64(size)) @@ -246,7 +246,7 @@ func initEmbed(v *ir.Node) { } } ggloblsym(slicedata, int32(off), obj.RODATA|obj.LOCAL) - sym := v.Sym.Linksym() + sym := v.Sym().Linksym() dsymptr(sym, 0, slicedata, 0) } } diff --git a/src/cmd/compile/internal/gc/escape.go b/src/cmd/compile/internal/gc/escape.go index a0aa516d9a..866bdf8a6f 100644 --- a/src/cmd/compile/internal/gc/escape.go +++ b/src/cmd/compile/internal/gc/escape.go @@ -149,7 +149,7 @@ func init() { // escFmt is called from node printing to print information about escape analysis results. func escFmt(n *ir.Node, short bool) string { text := "" - switch n.Esc { + switch n.Esc() { case EscUnknown: break @@ -165,7 +165,7 @@ func escFmt(n *ir.Node, short bool) string { } default: - text = fmt.Sprintf("esc(%d)", n.Esc) + text = fmt.Sprintf("esc(%d)", n.Esc()) } if e, ok := n.Opt().(*EscLocation); ok && e.loopDepth != 0 { @@ -181,7 +181,7 @@ func escFmt(n *ir.Node, short bool) string { // functions. func escapeFuncs(fns []*ir.Node, recursive bool) { for _, fn := range fns { - if fn.Op != ir.ODCLFUNC { + if fn.Op() != ir.ODCLFUNC { base.Fatalf("unexpected node: %v", fn) } } @@ -203,10 +203,10 @@ func escapeFuncs(fns []*ir.Node, recursive bool) { } func (e *Escape) initFunc(fn *ir.Node) { - if fn.Op != ir.ODCLFUNC || fn.Esc != EscFuncUnknown { + if fn.Op() != ir.ODCLFUNC || fn.Esc() != EscFuncUnknown { base.Fatalf("unexpected node: %v", fn) } - fn.Esc = EscFuncPlanned + fn.SetEsc(EscFuncPlanned) if base.Flag.LowerM > 3 { ir.Dump("escAnalyze", fn) } @@ -215,27 +215,27 @@ func (e *Escape) initFunc(fn *ir.Node) { e.loopDepth = 1 // Allocate locations for local variables. - for _, dcl := range fn.Func.Dcl { - if dcl.Op == ir.ONAME { + for _, dcl := range fn.Func().Dcl { + if dcl.Op() == ir.ONAME { e.newLoc(dcl, false) } } } func (e *Escape) walkFunc(fn *ir.Node) { - fn.Esc = EscFuncStarted + fn.SetEsc(EscFuncStarted) // Identify labels that mark the head of an unstructured loop. - ir.InspectList(fn.Nbody, func(n *ir.Node) bool { - switch n.Op { + ir.InspectList(fn.Body(), func(n *ir.Node) bool { + switch n.Op() { case ir.OLABEL: - n.Sym.Label = ir.AsTypesNode(nonlooping) + n.Sym().Label = ir.AsTypesNode(nonlooping) case ir.OGOTO: // If we visited the label before the goto, // then this is a looping label. - if n.Sym.Label == ir.AsTypesNode(nonlooping) { - n.Sym.Label = ir.AsTypesNode(looping) + if n.Sym().Label == ir.AsTypesNode(nonlooping) { + n.Sym().Label = ir.AsTypesNode(looping) } } @@ -244,7 +244,7 @@ func (e *Escape) walkFunc(fn *ir.Node) { e.curfn = fn e.loopDepth = 1 - e.block(fn.Nbody) + e.block(fn.Body()) } // Below we implement the methods for walking the AST and recording @@ -288,9 +288,9 @@ func (e *Escape) stmt(n *ir.Node) { fmt.Printf("%v:[%d] %v stmt: %v\n", base.FmtPos(base.Pos), e.loopDepth, funcSym(e.curfn), n) } - e.stmts(n.Ninit) + e.stmts(n.Init()) - switch n.Op { + switch n.Op() { default: base.Fatalf("unexpected stmt: %v", n) @@ -301,16 +301,16 @@ func (e *Escape) stmt(n *ir.Node) { // TODO(mdempsky): Handle dead code? case ir.OBLOCK: - e.stmts(n.List) + e.stmts(n.List()) case ir.ODCL: // Record loop depth at declaration. - if !ir.IsBlank(n.Left) { - e.dcl(n.Left) + if !ir.IsBlank(n.Left()) { + e.dcl(n.Left()) } case ir.OLABEL: - switch ir.AsNode(n.Sym.Label) { + switch ir.AsNode(n.Sym().Label) { case nonlooping: if base.Flag.LowerM > 2 { fmt.Printf("%v:%v non-looping label\n", base.FmtPos(base.Pos), n) @@ -323,109 +323,109 @@ func (e *Escape) stmt(n *ir.Node) { default: base.Fatalf("label missing tag") } - n.Sym.Label = nil + n.Sym().Label = nil case ir.OIF: - e.discard(n.Left) - e.block(n.Nbody) - e.block(n.Rlist) + e.discard(n.Left()) + e.block(n.Body()) + e.block(n.Rlist()) case ir.OFOR, ir.OFORUNTIL: e.loopDepth++ - e.discard(n.Left) - e.stmt(n.Right) - e.block(n.Nbody) + e.discard(n.Left()) + e.stmt(n.Right()) + e.block(n.Body()) e.loopDepth-- case ir.ORANGE: // for List = range Right { Nbody } e.loopDepth++ - ks := e.addrs(n.List) - e.block(n.Nbody) + ks := e.addrs(n.List()) + e.block(n.Body()) e.loopDepth-- // Right is evaluated outside the loop. k := e.discardHole() if len(ks) >= 2 { - if n.Right.Type.IsArray() { + if n.Right().Type().IsArray() { k = ks[1].note(n, "range") } else { k = ks[1].deref(n, "range-deref") } } - e.expr(e.later(k), n.Right) + e.expr(e.later(k), n.Right()) case ir.OSWITCH: - typesw := n.Left != nil && n.Left.Op == ir.OTYPESW + typesw := n.Left() != nil && n.Left().Op() == ir.OTYPESW var ks []EscHole - for _, cas := range n.List.Slice() { // cases - if typesw && n.Left.Left != nil { - cv := cas.Rlist.First() + for _, cas := range n.List().Slice() { // cases + if typesw && n.Left().Left() != nil { + cv := cas.Rlist().First() k := e.dcl(cv) // type switch variables have no ODCL. - if cv.Type.HasPointers() { - ks = append(ks, k.dotType(cv.Type, cas, "switch case")) + if cv.Type().HasPointers() { + ks = append(ks, k.dotType(cv.Type(), cas, "switch case")) } } - e.discards(cas.List) - e.block(cas.Nbody) + e.discards(cas.List()) + e.block(cas.Body()) } if typesw { - e.expr(e.teeHole(ks...), n.Left.Right) + e.expr(e.teeHole(ks...), n.Left().Right()) } else { - e.discard(n.Left) + e.discard(n.Left()) } case ir.OSELECT: - for _, cas := range n.List.Slice() { - e.stmt(cas.Left) - e.block(cas.Nbody) + for _, cas := range n.List().Slice() { + e.stmt(cas.Left()) + e.block(cas.Body()) } case ir.OSELRECV: - e.assign(n.Left, n.Right, "selrecv", n) + e.assign(n.Left(), n.Right(), "selrecv", n) case ir.OSELRECV2: - e.assign(n.Left, n.Right, "selrecv", n) - e.assign(n.List.First(), nil, "selrecv", n) + e.assign(n.Left(), n.Right(), "selrecv", n) + e.assign(n.List().First(), nil, "selrecv", n) case ir.ORECV: // TODO(mdempsky): Consider e.discard(n.Left). e.exprSkipInit(e.discardHole(), n) // already visited n.Ninit case ir.OSEND: - e.discard(n.Left) - e.assignHeap(n.Right, "send", n) + e.discard(n.Left()) + e.assignHeap(n.Right(), "send", n) case ir.OAS, ir.OASOP: - e.assign(n.Left, n.Right, "assign", n) + e.assign(n.Left(), n.Right(), "assign", n) case ir.OAS2: - for i, nl := range n.List.Slice() { - e.assign(nl, n.Rlist.Index(i), "assign-pair", n) + for i, nl := range n.List().Slice() { + e.assign(nl, n.Rlist().Index(i), "assign-pair", n) } case ir.OAS2DOTTYPE: // v, ok = x.(type) - e.assign(n.List.First(), n.Right, "assign-pair-dot-type", n) - e.assign(n.List.Second(), nil, "assign-pair-dot-type", n) + e.assign(n.List().First(), n.Right(), "assign-pair-dot-type", n) + e.assign(n.List().Second(), nil, "assign-pair-dot-type", n) case ir.OAS2MAPR: // v, ok = m[k] - e.assign(n.List.First(), n.Right, "assign-pair-mapr", n) - e.assign(n.List.Second(), nil, "assign-pair-mapr", n) + e.assign(n.List().First(), n.Right(), "assign-pair-mapr", n) + e.assign(n.List().Second(), nil, "assign-pair-mapr", n) case ir.OAS2RECV: // v, ok = <-ch - e.assign(n.List.First(), n.Right, "assign-pair-receive", n) - e.assign(n.List.Second(), nil, "assign-pair-receive", n) + e.assign(n.List().First(), n.Right(), "assign-pair-receive", n) + e.assign(n.List().Second(), nil, "assign-pair-receive", n) case ir.OAS2FUNC: - e.stmts(n.Right.Ninit) - e.call(e.addrs(n.List), n.Right, nil) + e.stmts(n.Right().Init()) + e.call(e.addrs(n.List()), n.Right(), nil) case ir.ORETURN: - results := e.curfn.Type.Results().FieldSlice() - for i, v := range n.List.Slice() { + results := e.curfn.Type().Results().FieldSlice() + for i, v := range n.List().Slice() { e.assign(ir.AsNode(results[i].Nname), v, "return", n) } case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OCLOSE, ir.OCOPY, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN, ir.ORECOVER: e.call(nil, n, nil) case ir.OGO, ir.ODEFER: - e.stmts(n.Left.Ninit) - e.call(nil, n.Left, n) + e.stmts(n.Left().Init()) + e.call(nil, n.Left(), n) case ir.ORETJMP: // TODO(mdempsky): What do? esc.go just ignores it. @@ -451,7 +451,7 @@ func (e *Escape) expr(k EscHole, n *ir.Node) { if n == nil { return } - e.stmts(n.Ninit) + e.stmts(n.Init()) e.exprSkipInit(k, n) } @@ -468,13 +468,13 @@ func (e *Escape) exprSkipInit(k EscHole, n *ir.Node) { uintptrEscapesHack := k.uintptrEscapesHack k.uintptrEscapesHack = false - if uintptrEscapesHack && n.Op == ir.OCONVNOP && n.Left.Type.IsUnsafePtr() { + if uintptrEscapesHack && n.Op() == ir.OCONVNOP && n.Left().Type().IsUnsafePtr() { // nop - } else if k.derefs >= 0 && !n.Type.HasPointers() { + } else if k.derefs >= 0 && !n.Type().HasPointers() { k = e.discardHole() } - switch n.Op { + switch n.Op() { default: base.Fatalf("unexpected expr: %v", n) @@ -488,61 +488,61 @@ func (e *Escape) exprSkipInit(k EscHole, n *ir.Node) { e.flow(k, e.oldLoc(n)) case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT: - e.discard(n.Left) + e.discard(n.Left()) case ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.ODIV, ir.OMOD, ir.OLSH, ir.ORSH, ir.OAND, ir.OANDNOT, ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE, ir.OANDAND, ir.OOROR: - e.discard(n.Left) - e.discard(n.Right) + e.discard(n.Left()) + e.discard(n.Right()) case ir.OADDR: - e.expr(k.addr(n, "address-of"), n.Left) // "address-of" + e.expr(k.addr(n, "address-of"), n.Left()) // "address-of" case ir.ODEREF: - e.expr(k.deref(n, "indirection"), n.Left) // "indirection" + e.expr(k.deref(n, "indirection"), n.Left()) // "indirection" case ir.ODOT, ir.ODOTMETH, ir.ODOTINTER: - e.expr(k.note(n, "dot"), n.Left) + e.expr(k.note(n, "dot"), n.Left()) case ir.ODOTPTR: - e.expr(k.deref(n, "dot of pointer"), n.Left) // "dot of pointer" + e.expr(k.deref(n, "dot of pointer"), n.Left()) // "dot of pointer" case ir.ODOTTYPE, ir.ODOTTYPE2: - e.expr(k.dotType(n.Type, n, "dot"), n.Left) + e.expr(k.dotType(n.Type(), n, "dot"), n.Left()) case ir.OINDEX: - if n.Left.Type.IsArray() { - e.expr(k.note(n, "fixed-array-index-of"), n.Left) + if n.Left().Type().IsArray() { + e.expr(k.note(n, "fixed-array-index-of"), n.Left()) } else { // TODO(mdempsky): Fix why reason text. - e.expr(k.deref(n, "dot of pointer"), n.Left) + e.expr(k.deref(n, "dot of pointer"), n.Left()) } - e.discard(n.Right) + e.discard(n.Right()) case ir.OINDEXMAP: - e.discard(n.Left) - e.discard(n.Right) + e.discard(n.Left()) + e.discard(n.Right()) case ir.OSLICE, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR, ir.OSLICESTR: - e.expr(k.note(n, "slice"), n.Left) + e.expr(k.note(n, "slice"), n.Left()) low, high, max := n.SliceBounds() e.discard(low) e.discard(high) e.discard(max) case ir.OCONV, ir.OCONVNOP: - if checkPtr(e.curfn, 2) && n.Type.IsUnsafePtr() && n.Left.Type.IsPtr() { + if checkPtr(e.curfn, 2) && n.Type().IsUnsafePtr() && n.Left().Type().IsPtr() { // When -d=checkptr=2 is enabled, treat // conversions to unsafe.Pointer as an // escaping operation. This allows better // runtime instrumentation, since we can more // easily detect object boundaries on the heap // than the stack. - e.assignHeap(n.Left, "conversion to unsafe.Pointer", n) - } else if n.Type.IsUnsafePtr() && n.Left.Type.IsUintptr() { - e.unsafeValue(k, n.Left) + e.assignHeap(n.Left(), "conversion to unsafe.Pointer", n) + } else if n.Type().IsUnsafePtr() && n.Left().Type().IsUintptr() { + e.unsafeValue(k, n.Left()) } else { - e.expr(k, n.Left) + e.expr(k, n.Left()) } case ir.OCONVIFACE: - if !n.Left.Type.IsInterface() && !isdirectiface(n.Left.Type) { + if !n.Left().Type().IsInterface() && !isdirectiface(n.Left().Type()) { k = e.spill(k, n) } - e.expr(k.note(n, "interface-converted"), n.Left) + e.expr(k.note(n, "interface-converted"), n.Left()) case ir.ORECV: - e.discard(n.Left) + e.discard(n.Left()) case ir.OCALLMETH, ir.OCALLFUNC, ir.OCALLINTER, ir.OLEN, ir.OCAP, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCOPY: e.call([]EscHole{k}, n, nil) @@ -552,13 +552,13 @@ func (e *Escape) exprSkipInit(k EscHole, n *ir.Node) { case ir.OMAKESLICE: e.spill(k, n) - e.discard(n.Left) - e.discard(n.Right) + e.discard(n.Left()) + e.discard(n.Right()) case ir.OMAKECHAN: - e.discard(n.Left) + e.discard(n.Left()) case ir.OMAKEMAP: e.spill(k, n) - e.discard(n.Left) + e.discard(n.Left()) case ir.ORECOVER: // nop @@ -583,15 +583,15 @@ func (e *Escape) exprSkipInit(k EscHole, n *ir.Node) { } paramK := e.tagHole(ks, ir.AsNode(m.Nname), m.Type.Recv()) - e.expr(e.teeHole(paramK, closureK), n.Left) + e.expr(e.teeHole(paramK, closureK), n.Left()) case ir.OPTRLIT: - e.expr(e.spill(k, n), n.Left) + e.expr(e.spill(k, n), n.Left()) case ir.OARRAYLIT: - for _, elt := range n.List.Slice() { - if elt.Op == ir.OKEY { - elt = elt.Right + for _, elt := range n.List().Slice() { + if elt.Op() == ir.OKEY { + elt = elt.Right() } e.expr(k.note(n, "array literal element"), elt) } @@ -600,89 +600,89 @@ func (e *Escape) exprSkipInit(k EscHole, n *ir.Node) { k = e.spill(k, n) k.uintptrEscapesHack = uintptrEscapesHack // for ...uintptr parameters - for _, elt := range n.List.Slice() { - if elt.Op == ir.OKEY { - elt = elt.Right + for _, elt := range n.List().Slice() { + if elt.Op() == ir.OKEY { + elt = elt.Right() } e.expr(k.note(n, "slice-literal-element"), elt) } case ir.OSTRUCTLIT: - for _, elt := range n.List.Slice() { - e.expr(k.note(n, "struct literal element"), elt.Left) + for _, elt := range n.List().Slice() { + e.expr(k.note(n, "struct literal element"), elt.Left()) } case ir.OMAPLIT: e.spill(k, n) // Map keys and values are always stored in the heap. - for _, elt := range n.List.Slice() { - e.assignHeap(elt.Left, "map literal key", n) - e.assignHeap(elt.Right, "map literal value", n) + for _, elt := range n.List().Slice() { + e.assignHeap(elt.Left(), "map literal key", n) + e.assignHeap(elt.Right(), "map literal value", n) } case ir.OCLOSURE: k = e.spill(k, n) // Link addresses of captured variables to closure. - for _, v := range n.Func.ClosureVars.Slice() { - if v.Op == ir.OXXX { // unnamed out argument; see dcl.go:/^funcargs + for _, v := range n.Func().ClosureVars.Slice() { + if v.Op() == ir.OXXX { // unnamed out argument; see dcl.go:/^funcargs continue } k := k - if !v.Name.Byval() { + if !v.Name().Byval() { k = k.addr(v, "reference") } - e.expr(k.note(n, "captured by a closure"), v.Name.Defn) + e.expr(k.note(n, "captured by a closure"), v.Name().Defn) } case ir.ORUNES2STR, ir.OBYTES2STR, ir.OSTR2RUNES, ir.OSTR2BYTES, ir.ORUNESTR: e.spill(k, n) - e.discard(n.Left) + e.discard(n.Left()) case ir.OADDSTR: e.spill(k, n) // Arguments of OADDSTR never escape; // runtime.concatstrings makes sure of that. - e.discards(n.List) + e.discards(n.List()) } } // unsafeValue evaluates a uintptr-typed arithmetic expression looking // for conversions from an unsafe.Pointer. func (e *Escape) unsafeValue(k EscHole, n *ir.Node) { - if n.Type.Etype != types.TUINTPTR { - base.Fatalf("unexpected type %v for %v", n.Type, n) + if n.Type().Etype != types.TUINTPTR { + base.Fatalf("unexpected type %v for %v", n.Type(), n) } - e.stmts(n.Ninit) + e.stmts(n.Init()) - switch n.Op { + switch n.Op() { case ir.OCONV, ir.OCONVNOP: - if n.Left.Type.IsUnsafePtr() { - e.expr(k, n.Left) + if n.Left().Type().IsUnsafePtr() { + e.expr(k, n.Left()) } else { - e.discard(n.Left) + e.discard(n.Left()) } case ir.ODOTPTR: if isReflectHeaderDataField(n) { - e.expr(k.deref(n, "reflect.Header.Data"), n.Left) + e.expr(k.deref(n, "reflect.Header.Data"), n.Left()) } else { - e.discard(n.Left) + e.discard(n.Left()) } case ir.OPLUS, ir.ONEG, ir.OBITNOT: - e.unsafeValue(k, n.Left) + e.unsafeValue(k, n.Left()) case ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.ODIV, ir.OMOD, ir.OAND, ir.OANDNOT: - e.unsafeValue(k, n.Left) - e.unsafeValue(k, n.Right) + e.unsafeValue(k, n.Left()) + e.unsafeValue(k, n.Right()) case ir.OLSH, ir.ORSH: - e.unsafeValue(k, n.Left) + e.unsafeValue(k, n.Left()) // RHS need not be uintptr-typed (#32959) and can't meaningfully // flow pointers anyway. - e.discard(n.Right) + e.discard(n.Right()) default: e.exprSkipInit(e.discardHole(), n) } @@ -711,7 +711,7 @@ func (e *Escape) addr(n *ir.Node) EscHole { k := e.heapHole() - switch n.Op { + switch n.Op() { default: base.Fatalf("unexpected addr: %v", n) case ir.ONAME: @@ -720,22 +720,22 @@ func (e *Escape) addr(n *ir.Node) EscHole { } k = e.oldLoc(n).asHole() case ir.ODOT: - k = e.addr(n.Left) + k = e.addr(n.Left()) case ir.OINDEX: - e.discard(n.Right) - if n.Left.Type.IsArray() { - k = e.addr(n.Left) + e.discard(n.Right()) + if n.Left().Type().IsArray() { + k = e.addr(n.Left()) } else { - e.discard(n.Left) + e.discard(n.Left()) } case ir.ODEREF, ir.ODOTPTR: e.discard(n) case ir.OINDEXMAP: - e.discard(n.Left) - e.assignHeap(n.Right, "key of map put", n) + e.discard(n.Left()) + e.assignHeap(n.Right(), "key of map put", n) } - if !n.Type.HasPointers() { + if !n.Type().HasPointers() { k = e.discardHole() } @@ -755,11 +755,11 @@ func (e *Escape) assign(dst, src *ir.Node, why string, where *ir.Node) { // Filter out some no-op assignments for escape analysis. ignore := dst != nil && src != nil && isSelfAssign(dst, src) if ignore && base.Flag.LowerM != 0 { - base.WarnfAt(where.Pos, "%v ignoring self-assignment in %S", funcSym(e.curfn), where) + base.WarnfAt(where.Pos(), "%v ignoring self-assignment in %S", funcSym(e.curfn), where) } k := e.addr(dst) - if dst != nil && dst.Op == ir.ODOTPTR && isReflectHeaderDataField(dst) { + if dst != nil && dst.Op() == ir.ODOTPTR && isReflectHeaderDataField(dst) { e.unsafeValue(e.heapHole().note(where, why), src) } else { if ignore { @@ -777,11 +777,11 @@ func (e *Escape) assignHeap(src *ir.Node, why string, where *ir.Node) { // should contain the holes representing where the function callee's // results flows; where is the OGO/ODEFER context of the call, if any. func (e *Escape) call(ks []EscHole, call, where *ir.Node) { - topLevelDefer := where != nil && where.Op == ir.ODEFER && e.loopDepth == 1 + topLevelDefer := where != nil && where.Op() == ir.ODEFER && e.loopDepth == 1 if topLevelDefer { // force stack allocation of defer record, unless // open-coded defers are used (see ssa.go) - where.Esc = EscNever + where.SetEsc(EscNever) } argument := func(k EscHole, arg *ir.Node) { @@ -797,66 +797,66 @@ func (e *Escape) call(ks []EscHole, call, where *ir.Node) { e.expr(k.note(call, "call parameter"), arg) } - switch call.Op { + switch call.Op() { default: - base.Fatalf("unexpected call op: %v", call.Op) + base.Fatalf("unexpected call op: %v", call.Op()) case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER: fixVariadicCall(call) // Pick out the function callee, if statically known. var fn *ir.Node - switch call.Op { + switch call.Op() { case ir.OCALLFUNC: - switch v := staticValue(call.Left); { - case v.Op == ir.ONAME && v.Class() == ir.PFUNC: + switch v := staticValue(call.Left()); { + case v.Op() == ir.ONAME && v.Class() == ir.PFUNC: fn = v - case v.Op == ir.OCLOSURE: - fn = v.Func.Nname + case v.Op() == ir.OCLOSURE: + fn = v.Func().Nname } case ir.OCALLMETH: - fn = methodExprName(call.Left) + fn = methodExprName(call.Left()) } - fntype := call.Left.Type + fntype := call.Left().Type() if fn != nil { - fntype = fn.Type + fntype = fn.Type() } if ks != nil && fn != nil && e.inMutualBatch(fn) { - for i, result := range fn.Type.Results().FieldSlice() { + for i, result := range fn.Type().Results().FieldSlice() { e.expr(ks[i], ir.AsNode(result.Nname)) } } if r := fntype.Recv(); r != nil { - argument(e.tagHole(ks, fn, r), call.Left.Left) + argument(e.tagHole(ks, fn, r), call.Left().Left()) } else { // Evaluate callee function expression. - argument(e.discardHole(), call.Left) + argument(e.discardHole(), call.Left()) } - args := call.List.Slice() + args := call.List().Slice() for i, param := range fntype.Params().FieldSlice() { argument(e.tagHole(ks, fn, param), args[i]) } case ir.OAPPEND: - args := call.List.Slice() + args := call.List().Slice() // Appendee slice may flow directly to the result, if // it has enough capacity. Alternatively, a new heap // slice might be allocated, and all slice elements // might flow to heap. appendeeK := ks[0] - if args[0].Type.Elem().HasPointers() { + if args[0].Type().Elem().HasPointers() { appendeeK = e.teeHole(appendeeK, e.heapHole().deref(call, "appendee slice")) } argument(appendeeK, args[0]) if call.IsDDD() { appendedK := e.discardHole() - if args[1].Type.IsSlice() && args[1].Type.Elem().HasPointers() { + if args[1].Type().IsSlice() && args[1].Type().Elem().HasPointers() { appendedK = e.heapHole().deref(call, "appended slice...") } argument(appendedK, args[1]) @@ -867,26 +867,26 @@ func (e *Escape) call(ks []EscHole, call, where *ir.Node) { } case ir.OCOPY: - argument(e.discardHole(), call.Left) + argument(e.discardHole(), call.Left()) copiedK := e.discardHole() - if call.Right.Type.IsSlice() && call.Right.Type.Elem().HasPointers() { + if call.Right().Type().IsSlice() && call.Right().Type().Elem().HasPointers() { copiedK = e.heapHole().deref(call, "copied slice") } - argument(copiedK, call.Right) + argument(copiedK, call.Right()) case ir.OPANIC: - argument(e.heapHole(), call.Left) + argument(e.heapHole(), call.Left()) case ir.OCOMPLEX: - argument(e.discardHole(), call.Left) - argument(e.discardHole(), call.Right) + argument(e.discardHole(), call.Left()) + argument(e.discardHole(), call.Right()) case ir.ODELETE, ir.OPRINT, ir.OPRINTN, ir.ORECOVER: - for _, arg := range call.List.Slice() { + for _, arg := range call.List().Slice() { argument(e.discardHole(), arg) } case ir.OLEN, ir.OCAP, ir.OREAL, ir.OIMAG, ir.OCLOSE: - argument(e.discardHole(), call.Left) + argument(e.discardHole(), call.Left()) } } @@ -936,8 +936,8 @@ func (e *Escape) tagHole(ks []EscHole, fn *ir.Node, param *types.Field) EscHole // should be incorporated directly into the flow graph instead of // relying on its escape analysis tagging. func (e *Escape) inMutualBatch(fn *ir.Node) bool { - if fn.Name.Defn != nil && fn.Name.Defn.Esc < EscFuncTagged { - if fn.Name.Defn.Esc == EscFuncUnknown { + if fn.Name().Defn != nil && fn.Name().Defn.Esc() < EscFuncTagged { + if fn.Name().Defn.Esc() == EscFuncUnknown { base.Fatalf("graph inconsistency") } return true @@ -1053,9 +1053,9 @@ func (e *Escape) later(k EscHole) EscHole { // canonicalNode returns the canonical *Node that n logically // represents. func canonicalNode(n *ir.Node) *ir.Node { - if n != nil && n.Op == ir.ONAME && n.Name.IsClosureVar() { - n = n.Name.Defn - if n.Name.IsClosureVar() { + if n != nil && n.Op() == ir.ONAME && n.Name().IsClosureVar() { + n = n.Name().Defn + if n.Name().IsClosureVar() { base.Fatalf("still closure var") } } @@ -1067,8 +1067,8 @@ func (e *Escape) newLoc(n *ir.Node, transient bool) *EscLocation { if e.curfn == nil { base.Fatalf("e.curfn isn't set") } - if n != nil && n.Type != nil && n.Type.NotInHeap() { - base.ErrorfAt(n.Pos, "%v is incomplete (or unallocatable); stack allocation disallowed", n.Type) + if n != nil && n.Type() != nil && n.Type().NotInHeap() { + base.ErrorfAt(n.Pos(), "%v is incomplete (or unallocatable); stack allocation disallowed", n.Type()) } n = canonicalNode(n) @@ -1080,8 +1080,8 @@ func (e *Escape) newLoc(n *ir.Node, transient bool) *EscLocation { } e.allLocs = append(e.allLocs, loc) if n != nil { - if n.Op == ir.ONAME && n.Name.Curfn != e.curfn { - base.Fatalf("curfn mismatch: %v != %v", n.Name.Curfn, e.curfn) + if n.Op() == ir.ONAME && n.Name().Curfn != e.curfn { + base.Fatalf("curfn mismatch: %v != %v", n.Name().Curfn, e.curfn) } if n.HasOpt() { @@ -1115,13 +1115,13 @@ func (e *Escape) flow(k EscHole, src *EscLocation) { } if dst.escapes && k.derefs < 0 { // dst = &src if base.Flag.LowerM >= 2 || logopt.Enabled() { - pos := base.FmtPos(src.n.Pos) + pos := base.FmtPos(src.n.Pos()) if base.Flag.LowerM >= 2 { fmt.Printf("%s: %v escapes to heap:\n", pos, src.n) } explanation := e.explainFlow(pos, dst, src, k.derefs, k.notes, []*logopt.LoggedOpt{}) if logopt.Enabled() { - logopt.LogOpt(src.n.Pos, "escapes", "escape", ir.FuncName(e.curfn), fmt.Sprintf("%v escapes to heap", src.n), explanation) + logopt.LogOpt(src.n.Pos(), "escapes", "escape", ir.FuncName(e.curfn), fmt.Sprintf("%v escapes to heap", src.n), explanation) } } @@ -1218,11 +1218,11 @@ func (e *Escape) walkOne(root *EscLocation, walkgen uint32, enqueue func(*EscLoc if l.isName(ir.PPARAM) { if (logopt.Enabled() || base.Flag.LowerM >= 2) && !l.escapes { if base.Flag.LowerM >= 2 { - fmt.Printf("%s: parameter %v leaks to %s with derefs=%d:\n", base.FmtPos(l.n.Pos), l.n, e.explainLoc(root), derefs) + fmt.Printf("%s: parameter %v leaks to %s with derefs=%d:\n", base.FmtPos(l.n.Pos()), l.n, e.explainLoc(root), derefs) } explanation := e.explainPath(root, l) if logopt.Enabled() { - logopt.LogOpt(l.n.Pos, "leak", "escape", ir.FuncName(e.curfn), + logopt.LogOpt(l.n.Pos(), "leak", "escape", ir.FuncName(e.curfn), fmt.Sprintf("parameter %v leaks to %s with derefs=%d", l.n, e.explainLoc(root), derefs), explanation) } } @@ -1235,11 +1235,11 @@ func (e *Escape) walkOne(root *EscLocation, walkgen uint32, enqueue func(*EscLoc if addressOf && !l.escapes { if logopt.Enabled() || base.Flag.LowerM >= 2 { if base.Flag.LowerM >= 2 { - fmt.Printf("%s: %v escapes to heap:\n", base.FmtPos(l.n.Pos), l.n) + fmt.Printf("%s: %v escapes to heap:\n", base.FmtPos(l.n.Pos()), l.n) } explanation := e.explainPath(root, l) if logopt.Enabled() { - logopt.LogOpt(l.n.Pos, "escape", "escape", ir.FuncName(e.curfn), fmt.Sprintf("%v escapes to heap", l.n), explanation) + logopt.LogOpt(l.n.Pos(), "escape", "escape", ir.FuncName(e.curfn), fmt.Sprintf("%v escapes to heap", l.n), explanation) } } l.escapes = true @@ -1267,7 +1267,7 @@ func (e *Escape) walkOne(root *EscLocation, walkgen uint32, enqueue func(*EscLoc // explainPath prints an explanation of how src flows to the walk root. func (e *Escape) explainPath(root, src *EscLocation) []*logopt.LoggedOpt { visited := make(map[*EscLocation]bool) - pos := base.FmtPos(src.n.Pos) + pos := base.FmtPos(src.n.Pos()) var explanation []*logopt.LoggedOpt for { // Prevent infinite loop. @@ -1309,19 +1309,19 @@ func (e *Escape) explainFlow(pos string, dst, srcloc *EscLocation, derefs int, n if logopt.Enabled() { var epos src.XPos if notes != nil { - epos = notes.where.Pos + epos = notes.where.Pos() } else if srcloc != nil && srcloc.n != nil { - epos = srcloc.n.Pos + epos = srcloc.n.Pos() } explanation = append(explanation, logopt.NewLoggedOpt(epos, "escflow", "escape", ir.FuncName(e.curfn), flow)) } for note := notes; note != nil; note = note.next { if print { - fmt.Printf("%s: from %v (%v) at %s\n", pos, note.where, note.why, base.FmtPos(note.where.Pos)) + fmt.Printf("%s: from %v (%v) at %s\n", pos, note.where, note.why, base.FmtPos(note.where.Pos())) } if logopt.Enabled() { - explanation = append(explanation, logopt.NewLoggedOpt(note.where.Pos, "escflow", "escape", ir.FuncName(e.curfn), + explanation = append(explanation, logopt.NewLoggedOpt(note.where.Pos(), "escflow", "escape", ir.FuncName(e.curfn), fmt.Sprintf(" from %v (%v)", note.where, note.why))) } } @@ -1336,7 +1336,7 @@ func (e *Escape) explainLoc(l *EscLocation) string { // TODO(mdempsky): Omit entirely. return "{temp}" } - if l.n.Op == ir.ONAME { + if l.n.Op() == ir.ONAME { return fmt.Sprintf("%v", l.n) } return fmt.Sprintf("{storage for %v}", l.n) @@ -1360,7 +1360,7 @@ func (e *Escape) outlives(l, other *EscLocation) bool { // // var u int // okay to stack allocate // *(func() *int { return &u }()) = 42 - if containsClosure(other.curfn, l.curfn) && l.curfn.Func.ClosureCalled { + if containsClosure(other.curfn, l.curfn) && l.curfn.Func().ClosureCalled { return false } @@ -1395,7 +1395,7 @@ func (e *Escape) outlives(l, other *EscLocation) bool { // containsClosure reports whether c is a closure contained within f. func containsClosure(f, c *ir.Node) bool { - if f.Op != ir.ODCLFUNC || c.Op != ir.ODCLFUNC { + if f.Op() != ir.ODCLFUNC || c.Op() != ir.ODCLFUNC { base.Fatalf("bad containsClosure: %v, %v", f, c) } @@ -1406,8 +1406,8 @@ func containsClosure(f, c *ir.Node) bool { // Closures within function Foo are named like "Foo.funcN..." // TODO(mdempsky): Better way to recognize this. - fn := f.Func.Nname.Sym.Name - cn := c.Func.Nname.Sym.Name + fn := f.Func().Nname.Sym().Name + cn := c.Func().Nname.Sym().Name return len(cn) > len(fn) && cn[:len(fn)] == fn && cn[len(fn)] == '.' } @@ -1417,7 +1417,7 @@ func (l *EscLocation) leakTo(sink *EscLocation, derefs int) { // into the escape analysis tag, then record a return leak. if sink.isName(ir.PPARAMOUT) && sink.curfn == l.curfn { // TODO(mdempsky): Eliminate dependency on Vargen here. - ri := int(sink.n.Name.Vargen) - 1 + ri := int(sink.n.Name().Vargen) - 1 if ri < numEscResults { // Leak to result parameter. l.paramEsc.AddResult(ri, derefs) @@ -1432,11 +1432,11 @@ func (l *EscLocation) leakTo(sink *EscLocation, derefs int) { func (e *Escape) finish(fns []*ir.Node) { // Record parameter tags for package export data. for _, fn := range fns { - fn.Esc = EscFuncTagged + fn.SetEsc(EscFuncTagged) narg := 0 for _, fs := range &types.RecvsParams { - for _, f := range fs(fn.Type).Fields().Slice() { + for _, f := range fs(fn.Type()).Fields().Slice() { narg++ f.Note = e.paramTag(fn, narg, f) } @@ -1453,21 +1453,21 @@ func (e *Escape) finish(fns []*ir.Node) { // Update n.Esc based on escape analysis results. if loc.escapes { - if n.Op != ir.ONAME { + if n.Op() != ir.ONAME { if base.Flag.LowerM != 0 { - base.WarnfAt(n.Pos, "%S escapes to heap", n) + base.WarnfAt(n.Pos(), "%S escapes to heap", n) } if logopt.Enabled() { - logopt.LogOpt(n.Pos, "escape", "escape", ir.FuncName(e.curfn)) + logopt.LogOpt(n.Pos(), "escape", "escape", ir.FuncName(e.curfn)) } } - n.Esc = EscHeap + n.SetEsc(EscHeap) addrescapes(n) } else { - if base.Flag.LowerM != 0 && n.Op != ir.ONAME { - base.WarnfAt(n.Pos, "%S does not escape", n) + if base.Flag.LowerM != 0 && n.Op() != ir.ONAME { + base.WarnfAt(n.Pos(), "%S does not escape", n) } - n.Esc = EscNone + n.SetEsc(EscNone) if loc.transient { n.SetTransient(true) } @@ -1476,7 +1476,7 @@ func (e *Escape) finish(fns []*ir.Node) { } func (l *EscLocation) isName(c ir.Class) bool { - return l.n != nil && l.n.Op == ir.ONAME && l.n.Class() == c + return l.n != nil && l.n.Op() == ir.ONAME && l.n.Class() == c } const numEscResults = 7 @@ -1608,10 +1608,10 @@ const ( // funcSym returns fn.Func.Nname.Sym if no nils are encountered along the way. func funcSym(fn *ir.Node) *types.Sym { - if fn == nil || fn.Func.Nname == nil { + if fn == nil || fn.Func().Nname == nil { return nil } - return fn.Func.Nname.Sym + return fn.Func().Nname.Sym() } // Mark labels that have no backjumps to them as not increasing e.loopdepth. @@ -1639,11 +1639,11 @@ func isSliceSelfAssign(dst, src *ir.Node) bool { // when we evaluate it for dst and for src. // dst is ONAME dereference. - if dst.Op != ir.ODEREF && dst.Op != ir.ODOTPTR || dst.Left.Op != ir.ONAME { + if dst.Op() != ir.ODEREF && dst.Op() != ir.ODOTPTR || dst.Left().Op() != ir.ONAME { return false } // src is a slice operation. - switch src.Op { + switch src.Op() { case ir.OSLICE, ir.OSLICE3, ir.OSLICESTR: // OK. case ir.OSLICEARR, ir.OSLICE3ARR: @@ -1656,18 +1656,18 @@ func isSliceSelfAssign(dst, src *ir.Node) bool { // Pointer to an array is OK since it's not stored inside b directly. // For slicing an array (not pointer to array), there is an implicit OADDR. // We check that to determine non-pointer array slicing. - if src.Left.Op == ir.OADDR { + if src.Left().Op() == ir.OADDR { return false } default: return false } // slice is applied to ONAME dereference. - if src.Left.Op != ir.ODEREF && src.Left.Op != ir.ODOTPTR || src.Left.Left.Op != ir.ONAME { + if src.Left().Op() != ir.ODEREF && src.Left().Op() != ir.ODOTPTR || src.Left().Left().Op() != ir.ONAME { return false } // dst and src reference the same base ONAME. - return dst.Left == src.Left.Left + return dst.Left() == src.Left().Left() } // isSelfAssign reports whether assignment from src to dst can @@ -1687,15 +1687,15 @@ func isSelfAssign(dst, src *ir.Node) bool { // // These assignments do not change assigned object lifetime. - if dst == nil || src == nil || dst.Op != src.Op { + if dst == nil || src == nil || dst.Op() != src.Op() { return false } - switch dst.Op { + switch dst.Op() { case ir.ODOT, ir.ODOTPTR: // Safe trailing accessors that are permitted to differ. case ir.OINDEX: - if mayAffectMemory(dst.Right) || mayAffectMemory(src.Right) { + if mayAffectMemory(dst.Right()) || mayAffectMemory(src.Right()) { return false } default: @@ -1703,7 +1703,7 @@ func isSelfAssign(dst, src *ir.Node) bool { } // The expression prefix must be both "safe" and identical. - return samesafeexpr(dst.Left, src.Left) + return samesafeexpr(dst.Left(), src.Left()) } // mayAffectMemory reports whether evaluation of n may affect the program's @@ -1716,18 +1716,18 @@ func mayAffectMemory(n *ir.Node) bool { // // We're ignoring things like division by zero, index out of range, // and nil pointer dereference here. - switch n.Op { + switch n.Op() { case ir.ONAME, ir.OCLOSUREVAR, ir.OLITERAL, ir.ONIL: return false // Left+Right group. case ir.OINDEX, ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.OLSH, ir.ORSH, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD: - return mayAffectMemory(n.Left) || mayAffectMemory(n.Right) + return mayAffectMemory(n.Left()) || mayAffectMemory(n.Right()) // Left group. case ir.ODOT, ir.ODOTPTR, ir.ODEREF, ir.OCONVNOP, ir.OCONV, ir.OLEN, ir.OCAP, ir.ONOT, ir.OBITNOT, ir.OPLUS, ir.ONEG, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF: - return mayAffectMemory(n.Left) + return mayAffectMemory(n.Left()) default: return true @@ -1737,39 +1737,39 @@ func mayAffectMemory(n *ir.Node) bool { // heapAllocReason returns the reason the given Node must be heap // allocated, or the empty string if it doesn't. func heapAllocReason(n *ir.Node) string { - if n.Type == nil { + if n.Type() == nil { return "" } // Parameters are always passed via the stack. - if n.Op == ir.ONAME && (n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) { + if n.Op() == ir.ONAME && (n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) { return "" } - if n.Type.Width > maxStackVarSize { + if n.Type().Width > maxStackVarSize { return "too large for stack" } - if (n.Op == ir.ONEW || n.Op == ir.OPTRLIT) && n.Type.Elem().Width >= maxImplicitStackVarSize { + if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Width >= maxImplicitStackVarSize { return "too large for stack" } - if n.Op == ir.OCLOSURE && closureType(n).Size() >= maxImplicitStackVarSize { + if n.Op() == ir.OCLOSURE && closureType(n).Size() >= maxImplicitStackVarSize { return "too large for stack" } - if n.Op == ir.OCALLPART && partialCallType(n).Size() >= maxImplicitStackVarSize { + if n.Op() == ir.OCALLPART && partialCallType(n).Size() >= maxImplicitStackVarSize { return "too large for stack" } - if n.Op == ir.OMAKESLICE { - r := n.Right + if n.Op() == ir.OMAKESLICE { + r := n.Right() if r == nil { - r = n.Left + r = n.Left() } if !smallintconst(r) { return "non-constant size" } - if t := n.Type; t.Elem().Width != 0 && r.Int64Val() >= maxImplicitStackVarSize/t.Elem().Width { + if t := n.Type(); t.Elem().Width != 0 && r.Int64Val() >= maxImplicitStackVarSize/t.Elem().Width { return "too large for stack" } } @@ -1782,7 +1782,7 @@ func heapAllocReason(n *ir.Node) string { // Storage is allocated as necessary to allow the address // to be taken. func addrescapes(n *ir.Node) { - switch n.Op { + switch n.Op() { default: // Unexpected Op, probably due to a previous type error. Ignore. @@ -1796,13 +1796,13 @@ func addrescapes(n *ir.Node) { // if this is a tmpname (PAUTO), it was tagged by tmpname as not escaping. // on PPARAM it means something different. - if n.Class() == ir.PAUTO && n.Esc == EscNever { + if n.Class() == ir.PAUTO && n.Esc() == EscNever { break } // If a closure reference escapes, mark the outer variable as escaping. - if n.Name.IsClosureVar() { - addrescapes(n.Name.Defn) + if n.Name().IsClosureVar() { + addrescapes(n.Name().Defn) break } @@ -1823,13 +1823,13 @@ func addrescapes(n *ir.Node) { // then we're analyzing the inner closure but we need to move x to the // heap in f, not in the inner closure. Flip over to f before calling moveToHeap. oldfn := Curfn - Curfn = n.Name.Curfn - if Curfn.Op == ir.OCLOSURE { - Curfn = Curfn.Func.Decl + Curfn = n.Name().Curfn + if Curfn.Op() == ir.OCLOSURE { + Curfn = Curfn.Func().Decl panic("can't happen") } ln := base.Pos - base.Pos = Curfn.Pos + base.Pos = Curfn.Pos() moveToHeap(n) Curfn = oldfn base.Pos = ln @@ -1840,8 +1840,8 @@ func addrescapes(n *ir.Node) { // escape--the pointer inside x does, but that // is always a heap pointer anyway. case ir.ODOT, ir.OINDEX, ir.OPAREN, ir.OCONVNOP: - if !n.Left.Type.IsSlice() { - addrescapes(n.Left) + if !n.Left().Type().IsSlice() { + addrescapes(n.Left()) } } } @@ -1861,21 +1861,21 @@ func moveToHeap(n *ir.Node) { // Allocate a local stack variable to hold the pointer to the heap copy. // temp will add it to the function declaration list automatically. - heapaddr := temp(types.NewPtr(n.Type)) - heapaddr.Sym = lookup("&" + n.Sym.Name) - heapaddr.Orig.Sym = heapaddr.Sym - heapaddr.Pos = n.Pos + heapaddr := temp(types.NewPtr(n.Type())) + heapaddr.SetSym(lookup("&" + n.Sym().Name)) + heapaddr.Orig().SetSym(heapaddr.Sym()) + heapaddr.SetPos(n.Pos()) // Unset AutoTemp to persist the &foo variable name through SSA to // liveness analysis. // TODO(mdempsky/drchase): Cleaner solution? - heapaddr.Name.SetAutoTemp(false) + heapaddr.Name().SetAutoTemp(false) // Parameters have a local stack copy used at function start/end // in addition to the copy in the heap that may live longer than // the function. if n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT { - if n.Xoffset == types.BADWIDTH { + if n.Offset() == types.BADWIDTH { base.Fatalf("addrescapes before param assignment") } @@ -1883,28 +1883,28 @@ func moveToHeap(n *ir.Node) { // Preserve a copy so we can still write code referring to the original, // and substitute that copy into the function declaration list // so that analyses of the local (on-stack) variables use it. - stackcopy := NewName(n.Sym) - stackcopy.Type = n.Type - stackcopy.Xoffset = n.Xoffset + stackcopy := NewName(n.Sym()) + stackcopy.SetType(n.Type()) + stackcopy.SetOffset(n.Offset()) stackcopy.SetClass(n.Class()) - stackcopy.Name.Param.Heapaddr = heapaddr + stackcopy.Name().Param.Heapaddr = heapaddr if n.Class() == ir.PPARAMOUT { // Make sure the pointer to the heap copy is kept live throughout the function. // The function could panic at any point, and then a defer could recover. // Thus, we need the pointer to the heap copy always available so the // post-deferreturn code can copy the return value back to the stack. // See issue 16095. - heapaddr.Name.SetIsOutputParamHeapAddr(true) + heapaddr.Name().SetIsOutputParamHeapAddr(true) } - n.Name.Param.Stackcopy = stackcopy + n.Name().Param.Stackcopy = stackcopy // Substitute the stackcopy into the function variable list so that // liveness and other analyses use the underlying stack slot // and not the now-pseudo-variable n. found := false - for i, d := range Curfn.Func.Dcl { + for i, d := range Curfn.Func().Dcl { if d == n { - Curfn.Func.Dcl[i] = stackcopy + Curfn.Func().Dcl[i] = stackcopy found = true break } @@ -1917,16 +1917,16 @@ func moveToHeap(n *ir.Node) { if !found { base.Fatalf("cannot find %v in local variable list", n) } - Curfn.Func.Dcl = append(Curfn.Func.Dcl, n) + Curfn.Func().Dcl = append(Curfn.Func().Dcl, n) } // Modify n in place so that uses of n now mean indirection of the heapaddr. n.SetClass(ir.PAUTOHEAP) - n.Xoffset = 0 - n.Name.Param.Heapaddr = heapaddr - n.Esc = EscHeap + n.SetOffset(0) + n.Name().Param.Heapaddr = heapaddr + n.SetEsc(EscHeap) if base.Flag.LowerM != 0 { - base.WarnfAt(n.Pos, "moved to heap: %v", n) + base.WarnfAt(n.Pos(), "moved to heap: %v", n) } } @@ -1947,7 +1947,7 @@ func (e *Escape) paramTag(fn *ir.Node, narg int, f *types.Field) string { return fmt.Sprintf("arg#%d", narg) } - if fn.Nbody.Len() == 0 { + if fn.Body().Len() == 0 { // Assume that uintptr arguments must be held live across the call. // This is most important for syscall.Syscall. // See golang.org/issue/13372. @@ -1969,7 +1969,7 @@ func (e *Escape) paramTag(fn *ir.Node, narg int, f *types.Field) string { // External functions are assumed unsafe, unless // //go:noescape is given before the declaration. - if fn.Func.Pragma&ir.Noescape != 0 { + if fn.Func().Pragma&ir.Noescape != 0 { if base.Flag.LowerM != 0 && f.Sym != nil { base.WarnfAt(f.Pos, "%v does not escape", name()) } @@ -1983,7 +1983,7 @@ func (e *Escape) paramTag(fn *ir.Node, narg int, f *types.Field) string { return esc.Encode() } - if fn.Func.Pragma&ir.UintptrEscapes != 0 { + if fn.Func().Pragma&ir.UintptrEscapes != 0 { if f.Type.IsUintptr() { if base.Flag.LowerM != 0 { base.WarnfAt(f.Pos, "marking %v as escaping uintptr", name()) @@ -2028,7 +2028,7 @@ func (e *Escape) paramTag(fn *ir.Node, narg int, f *types.Field) string { } for i := 0; i < numEscResults; i++ { if x := esc.Result(i); x >= 0 { - res := fn.Type.Results().Field(i).Sym + res := fn.Type().Results().Field(i).Sym base.WarnfAt(f.Pos, "leaking param: %v to result %v level=%d", name(), res, x) } } diff --git a/src/cmd/compile/internal/gc/export.go b/src/cmd/compile/internal/gc/export.go index 36bbb75050..1f0288a591 100644 --- a/src/cmd/compile/internal/gc/export.go +++ b/src/cmd/compile/internal/gc/export.go @@ -25,13 +25,13 @@ var asmlist []*ir.Node // exportsym marks n for export (or reexport). func exportsym(n *ir.Node) { - if n.Sym.OnExportList() { + if n.Sym().OnExportList() { return } - n.Sym.SetOnExportList(true) + n.Sym().SetOnExportList(true) if base.Flag.E != 0 { - fmt.Printf("export symbol %v\n", n.Sym) + fmt.Printf("export symbol %v\n", n.Sym()) } exportlist = append(exportlist, n) @@ -42,21 +42,21 @@ func initname(s string) bool { } func autoexport(n *ir.Node, ctxt ir.Class) { - if n.Sym.Pkg != ir.LocalPkg { + if n.Sym().Pkg != ir.LocalPkg { return } if (ctxt != ir.PEXTERN && ctxt != ir.PFUNC) || dclcontext != ir.PEXTERN { return } - if n.Type != nil && n.Type.IsKind(types.TFUNC) && ir.IsMethod(n) { + if n.Type() != nil && n.Type().IsKind(types.TFUNC) && ir.IsMethod(n) { return } - if types.IsExported(n.Sym.Name) || initname(n.Sym.Name) { + if types.IsExported(n.Sym().Name) || initname(n.Sym().Name) { exportsym(n) } - if base.Flag.AsmHdr != "" && !n.Sym.Asm() { - n.Sym.SetAsm(true) + if base.Flag.AsmHdr != "" && !n.Sym().Asm() { + n.Sym().SetAsm(true) asmlist = append(asmlist, n) } } @@ -89,7 +89,7 @@ func importsym(ipkg *types.Pkg, s *types.Sym, op ir.Op) *ir.Node { s.SetPkgDef(ir.AsTypesNode(n)) s.Importdef = ipkg } - if n.Op != ir.ONONAME && n.Op != op { + if n.Op() != ir.ONONAME && n.Op() != op { redeclare(base.Pos, s, fmt.Sprintf("during import %q", ipkg.Path)) } return n @@ -100,18 +100,18 @@ func importsym(ipkg *types.Pkg, s *types.Sym, op ir.Op) *ir.Node { // ipkg is the package being imported func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type { n := importsym(ipkg, s, ir.OTYPE) - if n.Op != ir.OTYPE { + if n.Op() != ir.OTYPE { t := types.New(types.TFORW) t.Sym = s t.Nod = ir.AsTypesNode(n) - n.Op = ir.OTYPE - n.Pos = pos - n.Type = t + n.SetOp(ir.OTYPE) + n.SetPos(pos) + n.SetType(t) n.SetClass(ir.PEXTERN) } - t := n.Type + t := n.Type() if t == nil { base.Fatalf("importtype %v", s) } @@ -122,20 +122,20 @@ func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type { // ipkg is the package being imported func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op ir.Op, ctxt ir.Class, t *types.Type) *ir.Node { n := importsym(ipkg, s, op) - if n.Op != ir.ONONAME { - if n.Op == op && (n.Class() != ctxt || !types.Identical(n.Type, t)) { + if n.Op() != ir.ONONAME { + if n.Op() == op && (n.Class() != ctxt || !types.Identical(n.Type(), t)) { redeclare(base.Pos, s, fmt.Sprintf("during import %q", ipkg.Path)) } return nil } - n.Op = op - n.Pos = pos + n.SetOp(op) + n.SetPos(pos) n.SetClass(ctxt) if ctxt == ir.PFUNC { - n.Sym.SetFunc(true) + n.Sym().SetFunc(true) } - n.Type = t + n.SetType(t) return n } @@ -162,7 +162,7 @@ func importfunc(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) { return } - n.Func = new(ir.Func) + n.SetFunc(new(ir.Func)) if base.Flag.E != 0 { fmt.Printf("import func %v%S\n", s, t) @@ -202,26 +202,26 @@ func dumpasmhdr() { } fmt.Fprintf(b, "// generated by compile -asmhdr from package %s\n\n", ir.LocalPkg.Name) for _, n := range asmlist { - if n.Sym.IsBlank() { + if n.Sym().IsBlank() { continue } - switch n.Op { + switch n.Op() { case ir.OLITERAL: t := n.Val().Kind() if t == constant.Float || t == constant.Complex { break } - fmt.Fprintf(b, "#define const_%s %#v\n", n.Sym.Name, n.Val()) + fmt.Fprintf(b, "#define const_%s %#v\n", n.Sym().Name, n.Val()) case ir.OTYPE: - t := n.Type + t := n.Type() if !t.IsStruct() || t.StructType().Map != nil || t.IsFuncArgStruct() { break } - fmt.Fprintf(b, "#define %s__size %d\n", n.Sym.Name, int(t.Width)) + fmt.Fprintf(b, "#define %s__size %d\n", n.Sym().Name, int(t.Width)) for _, f := range t.Fields().Slice() { if !f.Sym.IsBlank() { - fmt.Fprintf(b, "#define %s_%s %d\n", n.Sym.Name, f.Sym.Name, int(f.Offset)) + fmt.Fprintf(b, "#define %s_%s %d\n", n.Sym().Name, f.Sym.Name, int(f.Offset)) } } } diff --git a/src/cmd/compile/internal/gc/gen.go b/src/cmd/compile/internal/gc/gen.go index 0f5294b17d..d7320f3ccc 100644 --- a/src/cmd/compile/internal/gc/gen.go +++ b/src/cmd/compile/internal/gc/gen.go @@ -31,13 +31,13 @@ func sysvar(name string) *obj.LSym { // isParamStackCopy reports whether this is the on-stack copy of a // function parameter that moved to the heap. func isParamStackCopy(n *ir.Node) bool { - return n.Op == ir.ONAME && (n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) && n.Name.Param.Heapaddr != nil + return n.Op() == ir.ONAME && (n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) && n.Name().Param.Heapaddr != nil } // isParamHeapCopy reports whether this is the on-heap copy of // a function parameter that moved to the heap. func isParamHeapCopy(n *ir.Node) bool { - return n.Op == ir.ONAME && n.Class() == ir.PAUTOHEAP && n.Name.Param.Stackcopy != nil + return n.Op() == ir.ONAME && n.Class() == ir.PAUTOHEAP && n.Name().Param.Stackcopy != nil } // autotmpname returns the name for an autotmp variable numbered n. @@ -56,7 +56,7 @@ func tempAt(pos src.XPos, curfn *ir.Node, t *types.Type) *ir.Node { if curfn == nil { base.Fatalf("no curfn for tempAt") } - if curfn.Op == ir.OCLOSURE { + if curfn.Op() == ir.OCLOSURE { ir.Dump("tempAt", curfn) base.Fatalf("adding tempAt to wrong closure function") } @@ -65,22 +65,22 @@ func tempAt(pos src.XPos, curfn *ir.Node, t *types.Type) *ir.Node { } s := &types.Sym{ - Name: autotmpname(len(curfn.Func.Dcl)), + Name: autotmpname(len(curfn.Func().Dcl)), Pkg: ir.LocalPkg, } n := ir.NewNameAt(pos, s) s.Def = ir.AsTypesNode(n) - n.Type = t + n.SetType(t) n.SetClass(ir.PAUTO) - n.Esc = EscNever - n.Name.Curfn = curfn - n.Name.SetUsed(true) - n.Name.SetAutoTemp(true) - curfn.Func.Dcl = append(curfn.Func.Dcl, n) + n.SetEsc(EscNever) + n.Name().Curfn = curfn + n.Name().SetUsed(true) + n.Name().SetAutoTemp(true) + curfn.Func().Dcl = append(curfn.Func().Dcl, n) dowidth(t) - return n.Orig + return n.Orig() } func temp(t *types.Type) *ir.Node { diff --git a/src/cmd/compile/internal/gc/gsubr.go b/src/cmd/compile/internal/gc/gsubr.go index cf1c85ce29..3416a00cd1 100644 --- a/src/cmd/compile/internal/gc/gsubr.go +++ b/src/cmd/compile/internal/gc/gsubr.go @@ -69,7 +69,7 @@ func newProgs(fn *ir.Node, worker int) *Progs { pp.next = pp.NewProg() pp.clearp(pp.next) - pp.pos = fn.Pos + pp.pos = fn.Pos() pp.settext(fn) // PCDATA tables implicitly start with index -1. pp.prevLive = LivenessIndex{-1, false} @@ -181,10 +181,10 @@ func (pp *Progs) settext(fn *ir.Node) { ptxt := pp.Prog(obj.ATEXT) pp.Text = ptxt - fn.Func.LSym.Func().Text = ptxt + fn.Func().LSym.Func().Text = ptxt ptxt.From.Type = obj.TYPE_MEM ptxt.From.Name = obj.NAME_EXTERN - ptxt.From.Sym = fn.Func.LSym + ptxt.From.Sym = fn.Func().LSym } // initLSym defines f's obj.LSym and initializes it based on the @@ -199,7 +199,7 @@ func initLSym(f *ir.Func, hasBody bool) { } if nam := f.Nname; !ir.IsBlank(nam) { - f.LSym = nam.Sym.Linksym() + f.LSym = nam.Sym().Linksym() if f.Pragma&ir.Systemstack != 0 { f.LSym.Set(obj.AttrCFunc, true) } @@ -221,7 +221,7 @@ func initLSym(f *ir.Func, hasBody bool) { } } - isLinknameExported := nam.Sym.Linkname != "" && (hasBody || hasDefABI) + isLinknameExported := nam.Sym().Linkname != "" && (hasBody || hasDefABI) if abi, ok := symabiRefs[f.LSym.Name]; (ok && abi == obj.ABI0) || isLinknameExported { // Either 1) this symbol is definitely // referenced as ABI0 from this package; or 2) @@ -281,7 +281,7 @@ func initLSym(f *ir.Func, hasBody bool) { // See test/recover.go for test cases and src/reflect/value.go // for the actual functions being considered. if base.Ctxt.Pkgpath == "reflect" { - switch f.Nname.Sym.Name { + switch f.Nname.Sym().Name { case "callReflect", "callMethod": flag |= obj.WRAPPER } @@ -291,20 +291,20 @@ func initLSym(f *ir.Func, hasBody bool) { } func ggloblnod(nam *ir.Node) { - s := nam.Sym.Linksym() + s := nam.Sym().Linksym() s.Gotype = ngotype(nam).Linksym() flags := 0 - if nam.Name.Readonly() { + if nam.Name().Readonly() { flags = obj.RODATA } - if nam.Type != nil && !nam.Type.HasPointers() { + if nam.Type() != nil && !nam.Type().HasPointers() { flags |= obj.NOPTR } - base.Ctxt.Globl(s, nam.Type.Width, flags) - if nam.Name.LibfuzzerExtraCounter() { + base.Ctxt.Globl(s, nam.Type().Width, flags) + if nam.Name().LibfuzzerExtraCounter() { s.Type = objabi.SLIBFUZZER_EXTRA_COUNTER } - if nam.Sym.Linkname != "" { + if nam.Sym().Linkname != "" { // Make sure linkname'd symbol is non-package. When a symbol is // both imported and linkname'd, s.Pkg may not set to "_" in // types.Sym.Linksym because LSym already exists. Set it here. diff --git a/src/cmd/compile/internal/gc/iexport.go b/src/cmd/compile/internal/gc/iexport.go index 212db2184e..281e2de43d 100644 --- a/src/cmd/compile/internal/gc/iexport.go +++ b/src/cmd/compile/internal/gc/iexport.go @@ -329,7 +329,7 @@ func (w *exportWriter) writeIndex(index map[*ir.Node]uint64, mainIndex bool) { } for n := range index { - pkgObjs[n.Sym.Pkg] = append(pkgObjs[n.Sym.Pkg], n) + pkgObjs[n.Sym().Pkg] = append(pkgObjs[n.Sym().Pkg], n) } var pkgs []*types.Pkg @@ -337,7 +337,7 @@ func (w *exportWriter) writeIndex(index map[*ir.Node]uint64, mainIndex bool) { pkgs = append(pkgs, pkg) sort.Slice(objs, func(i, j int) bool { - return objs[i].Sym.Name < objs[j].Sym.Name + return objs[i].Sym().Name < objs[j].Sym().Name }) } @@ -356,7 +356,7 @@ func (w *exportWriter) writeIndex(index map[*ir.Node]uint64, mainIndex bool) { objs := pkgObjs[pkg] w.uint64(uint64(len(objs))) for _, n := range objs { - w.string(n.Sym.Name) + w.string(n.Sym().Name) w.uint64(index[n]) } } @@ -395,12 +395,12 @@ func (p *iexporter) stringOff(s string) uint64 { // pushDecl adds n to the declaration work queue, if not already present. func (p *iexporter) pushDecl(n *ir.Node) { - if n.Sym == nil || ir.AsNode(n.Sym.Def) != n && n.Op != ir.OTYPE { - base.Fatalf("weird Sym: %v, %v", n, n.Sym) + if n.Sym() == nil || ir.AsNode(n.Sym().Def) != n && n.Op() != ir.OTYPE { + base.Fatalf("weird Sym: %v, %v", n, n.Sym()) } // Don't export predeclared declarations. - if n.Sym.Pkg == ir.BuiltinPkg || n.Sym.Pkg == unsafepkg { + if n.Sym().Pkg == ir.BuiltinPkg || n.Sym().Pkg == unsafepkg { return } @@ -425,16 +425,16 @@ type exportWriter struct { func (p *iexporter) doDecl(n *ir.Node) { w := p.newWriter() - w.setPkg(n.Sym.Pkg, false) + w.setPkg(n.Sym().Pkg, false) - switch n.Op { + switch n.Op() { case ir.ONAME: switch n.Class() { case ir.PEXTERN: // Variable. w.tag('V') - w.pos(n.Pos) - w.typ(n.Type) + w.pos(n.Pos()) + w.typ(n.Type()) w.varExt(n) case ir.PFUNC: @@ -444,8 +444,8 @@ func (p *iexporter) doDecl(n *ir.Node) { // Function. w.tag('F') - w.pos(n.Pos) - w.signature(n.Type) + w.pos(n.Pos()) + w.signature(n.Type()) w.funcExt(n) default: @@ -456,23 +456,23 @@ func (p *iexporter) doDecl(n *ir.Node) { // Constant. n = typecheck(n, ctxExpr) w.tag('C') - w.pos(n.Pos) - w.value(n.Type, n.Val()) + w.pos(n.Pos()) + w.value(n.Type(), n.Val()) case ir.OTYPE: - if IsAlias(n.Sym) { + if IsAlias(n.Sym()) { // Alias. w.tag('A') - w.pos(n.Pos) - w.typ(n.Type) + w.pos(n.Pos()) + w.typ(n.Type()) break } // Defined type. w.tag('T') - w.pos(n.Pos) + w.pos(n.Pos()) - underlying := n.Type.Orig + underlying := n.Type().Orig if underlying == types.Errortype.Orig { // For "type T error", use error as the // underlying type instead of error's own @@ -484,7 +484,7 @@ func (p *iexporter) doDecl(n *ir.Node) { } w.typ(underlying) - t := n.Type + t := n.Type() if t.IsInterface() { w.typeExt(t) break @@ -519,7 +519,7 @@ func (p *iexporter) doInline(f *ir.Node) { w := p.newWriter() w.setPkg(fnpkg(f), false) - w.stmtList(ir.AsNodes(f.Func.Inl.Body)) + w.stmtList(ir.AsNodes(f.Func().Inl.Body)) p.inlineIndex[f] = w.flush() } @@ -574,7 +574,7 @@ func (w *exportWriter) qualifiedIdent(n *ir.Node) { // Ensure any referenced declarations are written out too. w.p.pushDecl(n) - s := n.Sym + s := n.Sym() w.string(s.Name) w.pkg(s.Pkg) } @@ -956,36 +956,36 @@ func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) } // Compiler-specific extensions. func (w *exportWriter) varExt(n *ir.Node) { - w.linkname(n.Sym) - w.symIdx(n.Sym) + w.linkname(n.Sym()) + w.symIdx(n.Sym()) } func (w *exportWriter) funcExt(n *ir.Node) { - w.linkname(n.Sym) - w.symIdx(n.Sym) + w.linkname(n.Sym()) + w.symIdx(n.Sym()) // Escape analysis. for _, fs := range &types.RecvsParams { - for _, f := range fs(n.Type).FieldSlice() { + for _, f := range fs(n.Type()).FieldSlice() { w.string(f.Note) } } // Inline body. - if n.Func.Inl != nil { - w.uint64(1 + uint64(n.Func.Inl.Cost)) - if n.Func.ExportInline() { + if n.Func().Inl != nil { + w.uint64(1 + uint64(n.Func().Inl.Cost)) + if n.Func().ExportInline() { w.p.doInline(n) } // Endlineno for inlined function. - if n.Name.Defn != nil { - w.pos(n.Name.Defn.Func.Endlineno) + if n.Name().Defn != nil { + w.pos(n.Name().Defn.Func().Endlineno) } else { // When the exported node was defined externally, // e.g. io exports atomic.(*Value).Load or bytes exports errors.New. // Keep it as we don't distinguish this case in iimport.go. - w.pos(n.Func.Endlineno) + w.pos(n.Func().Endlineno) } } else { w.uint64(0) @@ -1038,7 +1038,7 @@ func (w *exportWriter) stmtList(list ir.Nodes) { } func (w *exportWriter) node(n *ir.Node) { - if ir.OpPrec[n.Op] < 0 { + if ir.OpPrec[n.Op()] < 0 { w.stmt(n) } else { w.expr(n) @@ -1048,19 +1048,19 @@ func (w *exportWriter) node(n *ir.Node) { // Caution: stmt will emit more than one node for statement nodes n that have a non-empty // n.Ninit and where n cannot have a natural init section (such as in "if", "for", etc.). func (w *exportWriter) stmt(n *ir.Node) { - if n.Ninit.Len() > 0 && !ir.StmtWithInit(n.Op) { + if n.Init().Len() > 0 && !ir.StmtWithInit(n.Op()) { // can't use stmtList here since we don't want the final OEND - for _, n := range n.Ninit.Slice() { + for _, n := range n.Init().Slice() { w.stmt(n) } } - switch op := n.Op; op { + switch op := n.Op(); op { case ir.ODCL: w.op(ir.ODCL) - w.pos(n.Left.Pos) - w.localName(n.Left) - w.typ(n.Left.Type) + w.pos(n.Left().Pos()) + w.localName(n.Left()) + w.typ(n.Left().Type()) // case ODCLFIELD: // unimplemented - handled by default case @@ -1069,74 +1069,74 @@ func (w *exportWriter) stmt(n *ir.Node) { // Don't export "v = " initializing statements, hope they're always // preceded by the DCL which will be re-parsed and typecheck to reproduce // the "v = " again. - if n.Right != nil { + if n.Right() != nil { w.op(ir.OAS) - w.pos(n.Pos) - w.expr(n.Left) - w.expr(n.Right) + w.pos(n.Pos()) + w.expr(n.Left()) + w.expr(n.Right()) } case ir.OASOP: w.op(ir.OASOP) - w.pos(n.Pos) + w.pos(n.Pos()) w.op(n.SubOp()) - w.expr(n.Left) + w.expr(n.Left()) if w.bool(!n.Implicit()) { - w.expr(n.Right) + w.expr(n.Right()) } case ir.OAS2: w.op(ir.OAS2) - w.pos(n.Pos) - w.exprList(n.List) - w.exprList(n.Rlist) + w.pos(n.Pos()) + w.exprList(n.List()) + w.exprList(n.Rlist()) case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV: w.op(ir.OAS2) - w.pos(n.Pos) - w.exprList(n.List) - w.exprList(ir.AsNodes([]*ir.Node{n.Right})) + w.pos(n.Pos()) + w.exprList(n.List()) + w.exprList(ir.AsNodes([]*ir.Node{n.Right()})) case ir.ORETURN: w.op(ir.ORETURN) - w.pos(n.Pos) - w.exprList(n.List) + w.pos(n.Pos()) + w.exprList(n.List()) // case ORETJMP: // unreachable - generated by compiler for trampolin routines case ir.OGO, ir.ODEFER: w.op(op) - w.pos(n.Pos) - w.expr(n.Left) + w.pos(n.Pos()) + w.expr(n.Left()) case ir.OIF: w.op(ir.OIF) - w.pos(n.Pos) - w.stmtList(n.Ninit) - w.expr(n.Left) - w.stmtList(n.Nbody) - w.stmtList(n.Rlist) + w.pos(n.Pos()) + w.stmtList(n.Init()) + w.expr(n.Left()) + w.stmtList(n.Body()) + w.stmtList(n.Rlist()) case ir.OFOR: w.op(ir.OFOR) - w.pos(n.Pos) - w.stmtList(n.Ninit) - w.exprsOrNil(n.Left, n.Right) - w.stmtList(n.Nbody) + w.pos(n.Pos()) + w.stmtList(n.Init()) + w.exprsOrNil(n.Left(), n.Right()) + w.stmtList(n.Body()) case ir.ORANGE: w.op(ir.ORANGE) - w.pos(n.Pos) - w.stmtList(n.List) - w.expr(n.Right) - w.stmtList(n.Nbody) + w.pos(n.Pos()) + w.stmtList(n.List()) + w.expr(n.Right()) + w.stmtList(n.Body()) case ir.OSELECT, ir.OSWITCH: w.op(op) - w.pos(n.Pos) - w.stmtList(n.Ninit) - w.exprsOrNil(n.Left, nil) + w.pos(n.Pos()) + w.stmtList(n.Init()) + w.exprsOrNil(n.Left(), nil) w.caseList(n) // case OCASE: @@ -1144,41 +1144,41 @@ func (w *exportWriter) stmt(n *ir.Node) { case ir.OFALL: w.op(ir.OFALL) - w.pos(n.Pos) + w.pos(n.Pos()) case ir.OBREAK, ir.OCONTINUE: w.op(op) - w.pos(n.Pos) - w.exprsOrNil(n.Left, nil) + w.pos(n.Pos()) + w.exprsOrNil(n.Left(), nil) case ir.OEMPTY: // nothing to emit case ir.OGOTO, ir.OLABEL: w.op(op) - w.pos(n.Pos) - w.string(n.Sym.Name) + w.pos(n.Pos()) + w.string(n.Sym().Name) default: - base.Fatalf("exporter: CANNOT EXPORT: %v\nPlease notify gri@\n", n.Op) + base.Fatalf("exporter: CANNOT EXPORT: %v\nPlease notify gri@\n", n.Op()) } } func (w *exportWriter) caseList(sw *ir.Node) { - namedTypeSwitch := sw.Op == ir.OSWITCH && sw.Left != nil && sw.Left.Op == ir.OTYPESW && sw.Left.Left != nil + namedTypeSwitch := sw.Op() == ir.OSWITCH && sw.Left() != nil && sw.Left().Op() == ir.OTYPESW && sw.Left().Left() != nil - cases := sw.List.Slice() + cases := sw.List().Slice() w.uint64(uint64(len(cases))) for _, cas := range cases { - if cas.Op != ir.OCASE { + if cas.Op() != ir.OCASE { base.Fatalf("expected OCASE, got %v", cas) } - w.pos(cas.Pos) - w.stmtList(cas.List) + w.pos(cas.Pos()) + w.stmtList(cas.List()) if namedTypeSwitch { - w.localName(cas.Rlist.First()) + w.localName(cas.Rlist().First()) } - w.stmtList(cas.Nbody) + w.stmtList(cas.Body()) } } @@ -1200,38 +1200,38 @@ func (w *exportWriter) expr(n *ir.Node) { // } // from exprfmt (fmt.go) - for n.Op == ir.OPAREN || n.Implicit() && (n.Op == ir.ODEREF || n.Op == ir.OADDR || n.Op == ir.ODOT || n.Op == ir.ODOTPTR) { - n = n.Left + for n.Op() == ir.OPAREN || n.Implicit() && (n.Op() == ir.ODEREF || n.Op() == ir.OADDR || n.Op() == ir.ODOT || n.Op() == ir.ODOTPTR) { + n = n.Left() } - switch op := n.Op; op { + switch op := n.Op(); op { // expressions // (somewhat closely following the structure of exprfmt in fmt.go) case ir.ONIL: - if !n.Type.HasNil() { - base.Fatalf("unexpected type for nil: %v", n.Type) + if !n.Type().HasNil() { + base.Fatalf("unexpected type for nil: %v", n.Type()) } - if n.Orig != nil && n.Orig != n { - w.expr(n.Orig) + if n.Orig() != nil && n.Orig() != n { + w.expr(n.Orig()) break } w.op(ir.OLITERAL) - w.pos(n.Pos) - w.typ(n.Type) + w.pos(n.Pos()) + w.typ(n.Type()) case ir.OLITERAL: w.op(ir.OLITERAL) - w.pos(n.Pos) - w.value(n.Type, n.Val()) + w.pos(n.Pos()) + w.value(n.Type(), n.Val()) case ir.OMETHEXPR: // Special case: explicit name of func (*T) method(...) is turned into pkg.(*T).method, // but for export, this should be rendered as (*pkg.T).meth. // These nodes have the special property that they are names with a left OTYPE and a right ONAME. w.op(ir.OXDOT) - w.pos(n.Pos) - w.expr(n.Left) // n.Left.Op == OTYPE - w.selector(n.Right.Sym) + w.pos(n.Pos()) + w.expr(n.Left()) // n.Left.Op == OTYPE + w.selector(n.Right().Sym()) case ir.ONAME: // Package scope name. @@ -1250,20 +1250,20 @@ func (w *exportWriter) expr(n *ir.Node) { case ir.OTYPE: w.op(ir.OTYPE) - w.typ(n.Type) + w.typ(n.Type()) case ir.OTYPESW: w.op(ir.OTYPESW) - w.pos(n.Pos) + w.pos(n.Pos()) var s *types.Sym - if n.Left != nil { - if n.Left.Op != ir.ONONAME { - base.Fatalf("expected ONONAME, got %v", n.Left) + if n.Left() != nil { + if n.Left().Op() != ir.ONONAME { + base.Fatalf("expected ONONAME, got %v", n.Left()) } - s = n.Left.Sym + s = n.Left().Sym() } w.localIdent(s, 0) // declared pseudo-variable, if any - w.exprsOrNil(n.Right, nil) + w.exprsOrNil(n.Right(), nil) // case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC: // should have been resolved by typechecking - handled by default case @@ -1276,25 +1276,25 @@ func (w *exportWriter) expr(n *ir.Node) { case ir.OPTRLIT: w.op(ir.OADDR) - w.pos(n.Pos) - w.expr(n.Left) + w.pos(n.Pos()) + w.expr(n.Left()) case ir.OSTRUCTLIT: w.op(ir.OSTRUCTLIT) - w.pos(n.Pos) - w.typ(n.Type) - w.elemList(n.List) // special handling of field names + w.pos(n.Pos()) + w.typ(n.Type()) + w.elemList(n.List()) // special handling of field names case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT: w.op(ir.OCOMPLIT) - w.pos(n.Pos) - w.typ(n.Type) - w.exprList(n.List) + w.pos(n.Pos()) + w.typ(n.Type()) + w.exprList(n.List()) case ir.OKEY: w.op(ir.OKEY) - w.pos(n.Pos) - w.exprsOrNil(n.Left, n.Right) + w.pos(n.Pos()) + w.exprsOrNil(n.Left(), n.Right()) // case OSTRUCTKEY: // unreachable - handled in case OSTRUCTLIT by elemList @@ -1302,40 +1302,40 @@ func (w *exportWriter) expr(n *ir.Node) { case ir.OCALLPART: // An OCALLPART is an OXDOT before type checking. w.op(ir.OXDOT) - w.pos(n.Pos) - w.expr(n.Left) + w.pos(n.Pos()) + w.expr(n.Left()) // Right node should be ONAME - w.selector(n.Right.Sym) + w.selector(n.Right().Sym()) case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH: w.op(ir.OXDOT) - w.pos(n.Pos) - w.expr(n.Left) - w.selector(n.Sym) + w.pos(n.Pos()) + w.expr(n.Left()) + w.selector(n.Sym()) case ir.ODOTTYPE, ir.ODOTTYPE2: w.op(ir.ODOTTYPE) - w.pos(n.Pos) - w.expr(n.Left) - w.typ(n.Type) + w.pos(n.Pos()) + w.expr(n.Left()) + w.typ(n.Type()) case ir.OINDEX, ir.OINDEXMAP: w.op(ir.OINDEX) - w.pos(n.Pos) - w.expr(n.Left) - w.expr(n.Right) + w.pos(n.Pos()) + w.expr(n.Left()) + w.expr(n.Right()) case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR: w.op(ir.OSLICE) - w.pos(n.Pos) - w.expr(n.Left) + w.pos(n.Pos()) + w.expr(n.Left()) low, high, _ := n.SliceBounds() w.exprsOrNil(low, high) case ir.OSLICE3, ir.OSLICE3ARR: w.op(ir.OSLICE3) - w.pos(n.Pos) - w.expr(n.Left) + w.pos(n.Pos()) + w.expr(n.Left()) low, high, max := n.SliceBounds() w.exprsOrNil(low, high) w.expr(max) @@ -1343,25 +1343,25 @@ func (w *exportWriter) expr(n *ir.Node) { case ir.OCOPY, ir.OCOMPLEX: // treated like other builtin calls (see e.g., OREAL) w.op(op) - w.pos(n.Pos) - w.expr(n.Left) - w.expr(n.Right) + w.pos(n.Pos()) + w.expr(n.Left()) + w.expr(n.Right()) w.op(ir.OEND) case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR: w.op(ir.OCONV) - w.pos(n.Pos) - w.expr(n.Left) - w.typ(n.Type) + w.pos(n.Pos()) + w.expr(n.Left()) + w.typ(n.Type()) case ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCAP, ir.OCLOSE, ir.ODELETE, ir.OLEN, ir.OMAKE, ir.ONEW, ir.OPANIC, ir.ORECOVER, ir.OPRINT, ir.OPRINTN: w.op(op) - w.pos(n.Pos) - if n.Left != nil { - w.expr(n.Left) + w.pos(n.Pos()) + if n.Left() != nil { + w.expr(n.Left()) w.op(ir.OEND) } else { - w.exprList(n.List) // emits terminating OEND + w.exprList(n.List()) // emits terminating OEND } // only append() calls may contain '...' arguments if op == ir.OAPPEND { @@ -1372,49 +1372,49 @@ func (w *exportWriter) expr(n *ir.Node) { case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG: w.op(ir.OCALL) - w.pos(n.Pos) - w.stmtList(n.Ninit) - w.expr(n.Left) - w.exprList(n.List) + w.pos(n.Pos()) + w.stmtList(n.Init()) + w.expr(n.Left()) + w.exprList(n.List()) w.bool(n.IsDDD()) case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE: w.op(op) // must keep separate from OMAKE for importer - w.pos(n.Pos) - w.typ(n.Type) + w.pos(n.Pos()) + w.typ(n.Type()) switch { default: // empty list w.op(ir.OEND) - case n.List.Len() != 0: // pre-typecheck - w.exprList(n.List) // emits terminating OEND - case n.Right != nil: - w.expr(n.Left) - w.expr(n.Right) + case n.List().Len() != 0: // pre-typecheck + w.exprList(n.List()) // emits terminating OEND + case n.Right() != nil: + w.expr(n.Left()) + w.expr(n.Right()) w.op(ir.OEND) - case n.Left != nil && (n.Op == ir.OMAKESLICE || !n.Left.Type.IsUntyped()): - w.expr(n.Left) + case n.Left() != nil && (n.Op() == ir.OMAKESLICE || !n.Left().Type().IsUntyped()): + w.expr(n.Left()) w.op(ir.OEND) } // unary expressions case ir.OPLUS, ir.ONEG, ir.OADDR, ir.OBITNOT, ir.ODEREF, ir.ONOT, ir.ORECV: w.op(op) - w.pos(n.Pos) - w.expr(n.Left) + w.pos(n.Pos()) + w.expr(n.Left()) // binary expressions case ir.OADD, ir.OAND, ir.OANDAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT, ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.OOROR, ir.ORSH, ir.OSEND, ir.OSUB, ir.OXOR: w.op(op) - w.pos(n.Pos) - w.expr(n.Left) - w.expr(n.Right) + w.pos(n.Pos()) + w.expr(n.Left()) + w.expr(n.Right()) case ir.OADDSTR: w.op(ir.OADDSTR) - w.pos(n.Pos) - w.exprList(n.List) + w.pos(n.Pos()) + w.exprList(n.List()) case ir.ODCLCONST: // if exporting, DCLCONST should just be removed as its usage @@ -1422,7 +1422,7 @@ func (w *exportWriter) expr(n *ir.Node) { default: base.Fatalf("cannot export %v (%d) node\n"+ - "\t==> please file an issue and assign to gri@", n.Op, int(n.Op)) + "\t==> please file an issue and assign to gri@", n.Op(), int(n.Op())) } } @@ -1450,8 +1450,8 @@ func (w *exportWriter) exprsOrNil(a, b *ir.Node) { func (w *exportWriter) elemList(list ir.Nodes) { w.uint64(uint64(list.Len())) for _, n := range list.Slice() { - w.selector(n.Sym) - w.expr(n.Left) + w.selector(n.Sym()) + w.expr(n.Left()) } } @@ -1464,11 +1464,11 @@ func (w *exportWriter) localName(n *ir.Node) { // PPARAM/PPARAMOUT, because we only want to include vargen in // non-param names. var v int32 - if n.Class() == ir.PAUTO || (n.Class() == ir.PAUTOHEAP && n.Name.Param.Stackcopy == nil) { - v = n.Name.Vargen + if n.Class() == ir.PAUTO || (n.Class() == ir.PAUTOHEAP && n.Name().Param.Stackcopy == nil) { + v = n.Name().Vargen } - w.localIdent(n.Sym, v) + w.localIdent(n.Sym(), v) } func (w *exportWriter) localIdent(s *types.Sym, v int32) { diff --git a/src/cmd/compile/internal/gc/iimport.go b/src/cmd/compile/internal/gc/iimport.go index 84386140bb..7106356665 100644 --- a/src/cmd/compile/internal/gc/iimport.go +++ b/src/cmd/compile/internal/gc/iimport.go @@ -42,7 +42,7 @@ var ( ) func expandDecl(n *ir.Node) { - if n.Op != ir.ONONAME { + if n.Op() != ir.ONONAME { return } @@ -56,7 +56,7 @@ func expandDecl(n *ir.Node) { } func expandInline(fn *ir.Node) { - if fn.Func.Inl.Body != nil { + if fn.Func().Inl.Body != nil { return } @@ -69,12 +69,12 @@ func expandInline(fn *ir.Node) { } func importReaderFor(n *ir.Node, importers map[*types.Sym]iimporterAndOffset) *importReader { - x, ok := importers[n.Sym] + x, ok := importers[n.Sym()] if !ok { return nil } - return x.p.newReader(x.off, n.Sym.Pkg) + return x.p.newReader(x.off, n.Sym().Pkg) } type intReader struct { @@ -282,8 +282,8 @@ func (r *importReader) setPkg() { } func (r *importReader) doDecl(n *ir.Node) { - if n.Op != ir.ONONAME { - base.Fatalf("doDecl: unexpected Op for %v: %v", n.Sym, n.Op) + if n.Op() != ir.ONONAME { + base.Fatalf("doDecl: unexpected Op for %v: %v", n.Sym(), n.Op()) } tag := r.byte() @@ -293,24 +293,24 @@ func (r *importReader) doDecl(n *ir.Node) { case 'A': typ := r.typ() - importalias(r.p.ipkg, pos, n.Sym, typ) + importalias(r.p.ipkg, pos, n.Sym(), typ) case 'C': typ := r.typ() val := r.value(typ) - importconst(r.p.ipkg, pos, n.Sym, typ, val) + importconst(r.p.ipkg, pos, n.Sym(), typ, val) case 'F': typ := r.signature(nil) - importfunc(r.p.ipkg, pos, n.Sym, typ) + importfunc(r.p.ipkg, pos, n.Sym(), typ) r.funcExt(n) case 'T': // Types can be recursive. We need to setup a stub // declaration before recursing. - t := importtype(r.p.ipkg, pos, n.Sym) + t := importtype(r.p.ipkg, pos, n.Sym()) // We also need to defer width calculations until // after the underlying type has been assigned. @@ -332,7 +332,7 @@ func (r *importReader) doDecl(n *ir.Node) { mtyp := r.signature(recv) m := newfuncnamel(mpos, methodSym(recv.Type, msym), new(ir.Func)) - m.Type = mtyp + m.SetType(mtyp) m.SetClass(ir.PFUNC) // methodSym already marked m.Sym as a function. @@ -350,7 +350,7 @@ func (r *importReader) doDecl(n *ir.Node) { case 'V': typ := r.typ() - importvar(r.p.ipkg, pos, n.Sym, typ) + importvar(r.p.ipkg, pos, n.Sym(), typ) r.varExt(n) default: @@ -500,13 +500,13 @@ func (r *importReader) typ1() *types.Type { // types. Therefore, this must be a package-scope // type. n := ir.AsNode(r.qualifiedIdent().PkgDef()) - if n.Op == ir.ONONAME { + if n.Op() == ir.ONONAME { expandDecl(n) } - if n.Op != ir.OTYPE { - base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op, n.Sym, n) + if n.Op() != ir.OTYPE { + base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n) } - return n.Type + return n.Type() case pointerType: return types.NewPtr(r.typ()) case sliceType: @@ -636,27 +636,27 @@ func (r *importReader) byte() byte { // Compiler-specific extensions. func (r *importReader) varExt(n *ir.Node) { - r.linkname(n.Sym) - r.symIdx(n.Sym) + r.linkname(n.Sym()) + r.symIdx(n.Sym()) } func (r *importReader) funcExt(n *ir.Node) { - r.linkname(n.Sym) - r.symIdx(n.Sym) + r.linkname(n.Sym()) + r.symIdx(n.Sym()) // Escape analysis. for _, fs := range &types.RecvsParams { - for _, f := range fs(n.Type).FieldSlice() { + for _, f := range fs(n.Type()).FieldSlice() { f.Note = r.string() } } // Inline body. if u := r.uint64(); u > 0 { - n.Func.Inl = &ir.Inline{ + n.Func().Inl = &ir.Inline{ Cost: int32(u - 1), } - n.Func.Endlineno = r.pos() + n.Func().Endlineno = r.pos() } } @@ -696,7 +696,7 @@ func (r *importReader) typeExt(t *types.Type) { var typeSymIdx = make(map[*types.Type][2]int64) func (r *importReader) doInline(n *ir.Node) { - if len(n.Func.Inl.Body) != 0 { + if len(n.Func().Inl.Body) != 0 { base.Fatalf("%v already has inline body", n) } @@ -712,15 +712,15 @@ func (r *importReader) doInline(n *ir.Node) { // functions). body = []*ir.Node{} } - n.Func.Inl.Body = body + n.Func().Inl.Body = body importlist = append(importlist, n) if base.Flag.E > 0 && base.Flag.LowerM > 2 { if base.Flag.LowerM > 3 { - fmt.Printf("inl body for %v %#v: %+v\n", n, n.Type, ir.AsNodes(n.Func.Inl.Body)) + fmt.Printf("inl body for %v %#v: %+v\n", n, n.Type(), ir.AsNodes(n.Func().Inl.Body)) } else { - fmt.Printf("inl body for %v %#v: %v\n", n, n.Type, ir.AsNodes(n.Func.Inl.Body)) + fmt.Printf("inl body for %v %#v: %v\n", n, n.Type(), ir.AsNodes(n.Func().Inl.Body)) } } } @@ -748,8 +748,8 @@ func (r *importReader) stmtList() []*ir.Node { break } // OBLOCK nodes may be created when importing ODCL nodes - unpack them - if n.Op == ir.OBLOCK { - list = append(list, n.List.Slice()...) + if n.Op() == ir.OBLOCK { + list = append(list, n.List().Slice()...) } else { list = append(list, n) } @@ -759,22 +759,22 @@ func (r *importReader) stmtList() []*ir.Node { } func (r *importReader) caseList(sw *ir.Node) []*ir.Node { - namedTypeSwitch := sw.Op == ir.OSWITCH && sw.Left != nil && sw.Left.Op == ir.OTYPESW && sw.Left.Left != nil + namedTypeSwitch := sw.Op() == ir.OSWITCH && sw.Left() != nil && sw.Left().Op() == ir.OTYPESW && sw.Left().Left() != nil cases := make([]*ir.Node, r.uint64()) for i := range cases { cas := ir.NodAt(r.pos(), ir.OCASE, nil, nil) - cas.List.Set(r.stmtList()) + cas.PtrList().Set(r.stmtList()) if namedTypeSwitch { // Note: per-case variables will have distinct, dotted // names after import. That's okay: swt.go only needs // Sym for diagnostics anyway. - caseVar := ir.NewNameAt(cas.Pos, r.ident()) + caseVar := ir.NewNameAt(cas.Pos(), r.ident()) declare(caseVar, dclcontext) - cas.Rlist.Set1(caseVar) - caseVar.Name.Defn = sw.Left + cas.PtrRlist().Set1(caseVar) + caseVar.Name().Defn = sw.Left() } - cas.Nbody.Set(r.stmtList()) + cas.PtrBody().Set(r.stmtList()) cases[i] = cas } return cases @@ -794,7 +794,7 @@ func (r *importReader) exprList() []*ir.Node { func (r *importReader) expr() *ir.Node { n := r.node() - if n != nil && n.Op == ir.OBLOCK { + if n != nil && n.Op() == ir.OBLOCK { base.Fatalf("unexpected block node: %v", n) } return n @@ -821,7 +821,7 @@ func (r *importReader) node() *ir.Node { n = ir.NewLiteral(r.value(typ)) } n = npos(pos, n) - n.Type = typ + n.SetType(typ) return n case ir.ONONAME: @@ -839,10 +839,10 @@ func (r *importReader) node() *ir.Node { case ir.OTYPESW: n := ir.NodAt(r.pos(), ir.OTYPESW, nil, nil) if s := r.ident(); s != nil { - n.Left = npos(n.Pos, newnoname(s)) + n.SetLeft(npos(n.Pos(), newnoname(s))) } right, _ := r.exprsOrNil() - n.Right = right + n.SetRight(right) return n // case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC: @@ -859,7 +859,7 @@ func (r *importReader) node() *ir.Node { savedlineno := base.Pos base.Pos = r.pos() n := ir.NodAt(base.Pos, ir.OCOMPLIT, nil, typenod(r.typ())) - n.List.Set(r.elemList()) // special handling of field names + n.PtrList().Set(r.elemList()) // special handling of field names base.Pos = savedlineno return n @@ -868,7 +868,7 @@ func (r *importReader) node() *ir.Node { case ir.OCOMPLIT: n := ir.NodAt(r.pos(), ir.OCOMPLIT, nil, typenod(r.typ())) - n.List.Set(r.exprList()) + n.PtrList().Set(r.exprList()) return n case ir.OKEY: @@ -894,7 +894,7 @@ func (r *importReader) node() *ir.Node { case ir.ODOTTYPE: n := ir.NodAt(r.pos(), ir.ODOTTYPE, r.expr(), nil) - n.Type = r.typ() + n.SetType(r.typ()) return n // case OINDEX, OINDEXMAP, OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR: @@ -907,7 +907,7 @@ func (r *importReader) node() *ir.Node { n := ir.NodAt(r.pos(), op, r.expr(), nil) low, high := r.exprsOrNil() var max *ir.Node - if n.Op.IsSlice3() { + if n.Op().IsSlice3() { max = r.expr() } n.SetSliceBounds(low, high, max) @@ -918,12 +918,12 @@ func (r *importReader) node() *ir.Node { case ir.OCONV: n := ir.NodAt(r.pos(), ir.OCONV, r.expr(), nil) - n.Type = r.typ() + n.SetType(r.typ()) return n case ir.OCOPY, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCAP, ir.OCLOSE, ir.ODELETE, ir.OLEN, ir.OMAKE, ir.ONEW, ir.OPANIC, ir.ORECOVER, ir.OPRINT, ir.OPRINTN: n := npos(r.pos(), builtinCall(op)) - n.List.Set(r.exprList()) + n.PtrList().Set(r.exprList()) if op == ir.OAPPEND { n.SetIsDDD(r.bool()) } @@ -934,16 +934,16 @@ func (r *importReader) node() *ir.Node { case ir.OCALL: n := ir.NodAt(r.pos(), ir.OCALL, nil, nil) - n.Ninit.Set(r.stmtList()) - n.Left = r.expr() - n.List.Set(r.exprList()) + n.PtrInit().Set(r.stmtList()) + n.SetLeft(r.expr()) + n.PtrList().Set(r.exprList()) n.SetIsDDD(r.bool()) return n case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE: n := npos(r.pos(), builtinCall(ir.OMAKE)) - n.List.Append(typenod(r.typ())) - n.List.Append(r.exprList()...) + n.PtrList().Append(typenod(r.typ())) + n.PtrList().Append(r.exprList()...) return n // unary expressions @@ -984,12 +984,12 @@ func (r *importReader) node() *ir.Node { case ir.OASOP: n := ir.NodAt(r.pos(), ir.OASOP, nil, nil) n.SetSubOp(r.op()) - n.Left = r.expr() + n.SetLeft(r.expr()) if !r.bool() { - n.Right = nodintconst(1) + n.SetRight(nodintconst(1)) n.SetImplicit(true) } else { - n.Right = r.expr() + n.SetRight(r.expr()) } return n @@ -998,13 +998,13 @@ func (r *importReader) node() *ir.Node { case ir.OAS2: n := ir.NodAt(r.pos(), ir.OAS2, nil, nil) - n.List.Set(r.exprList()) - n.Rlist.Set(r.exprList()) + n.PtrList().Set(r.exprList()) + n.PtrRlist().Set(r.exprList()) return n case ir.ORETURN: n := ir.NodAt(r.pos(), ir.ORETURN, nil, nil) - n.List.Set(r.exprList()) + n.PtrList().Set(r.exprList()) return n // case ORETJMP: @@ -1015,34 +1015,34 @@ func (r *importReader) node() *ir.Node { case ir.OIF: n := ir.NodAt(r.pos(), ir.OIF, nil, nil) - n.Ninit.Set(r.stmtList()) - n.Left = r.expr() - n.Nbody.Set(r.stmtList()) - n.Rlist.Set(r.stmtList()) + n.PtrInit().Set(r.stmtList()) + n.SetLeft(r.expr()) + n.PtrBody().Set(r.stmtList()) + n.PtrRlist().Set(r.stmtList()) return n case ir.OFOR: n := ir.NodAt(r.pos(), ir.OFOR, nil, nil) - n.Ninit.Set(r.stmtList()) + n.PtrInit().Set(r.stmtList()) left, right := r.exprsOrNil() - n.Left = left - n.Right = right - n.Nbody.Set(r.stmtList()) + n.SetLeft(left) + n.SetRight(right) + n.PtrBody().Set(r.stmtList()) return n case ir.ORANGE: n := ir.NodAt(r.pos(), ir.ORANGE, nil, nil) - n.List.Set(r.stmtList()) - n.Right = r.expr() - n.Nbody.Set(r.stmtList()) + n.PtrList().Set(r.stmtList()) + n.SetRight(r.expr()) + n.PtrBody().Set(r.stmtList()) return n case ir.OSELECT, ir.OSWITCH: n := ir.NodAt(r.pos(), op, nil, nil) - n.Ninit.Set(r.stmtList()) + n.PtrInit().Set(r.stmtList()) left, _ := r.exprsOrNil() - n.Left = left - n.List.Set(r.caseList(n)) + n.SetLeft(left) + n.PtrList().Set(r.caseList(n)) return n // case OCASE: @@ -1056,7 +1056,7 @@ func (r *importReader) node() *ir.Node { pos := r.pos() left, _ := r.exprsOrNil() if left != nil { - left = NewName(left.Sym) + left = NewName(left.Sym()) } return ir.NodAt(pos, op, left, nil) @@ -1065,7 +1065,7 @@ func (r *importReader) node() *ir.Node { case ir.OGOTO, ir.OLABEL: n := ir.NodAt(r.pos(), op, nil, nil) - n.Sym = lookup(r.string()) + n.SetSym(lookup(r.string())) return n case ir.OEND: diff --git a/src/cmd/compile/internal/gc/init.go b/src/cmd/compile/internal/gc/init.go index f3c302f6be..b66ee6f953 100644 --- a/src/cmd/compile/internal/gc/init.go +++ b/src/cmd/compile/internal/gc/init.go @@ -46,16 +46,16 @@ func fninit(n []*ir.Node) { // Make a function that contains all the initialization statements. if len(nf) > 0 { - base.Pos = nf[0].Pos // prolog/epilog gets line number of first init stmt + base.Pos = nf[0].Pos() // prolog/epilog gets line number of first init stmt initializers := lookup("init") fn := dclfunc(initializers, ir.Nod(ir.OTFUNC, nil, nil)) - for _, dcl := range initTodo.Func.Dcl { - dcl.Name.Curfn = fn + for _, dcl := range initTodo.Func().Dcl { + dcl.Name().Curfn = fn } - fn.Func.Dcl = append(fn.Func.Dcl, initTodo.Func.Dcl...) - initTodo.Func.Dcl = nil + fn.Func().Dcl = append(fn.Func().Dcl, initTodo.Func().Dcl...) + initTodo.Func().Dcl = nil - fn.Nbody.Set(nf) + fn.PtrBody().Set(nf) funcbody() fn = typecheck(fn, ctxStmt) @@ -65,7 +65,7 @@ func fninit(n []*ir.Node) { xtop = append(xtop, fn) fns = append(fns, initializers.Linksym()) } - if initTodo.Func.Dcl != nil { + if initTodo.Func().Dcl != nil { // We only generate temps using initTodo if there // are package-scope initialization statements, so // something's weird if we get here. @@ -76,9 +76,9 @@ func fninit(n []*ir.Node) { // Record user init functions. for i := 0; i < renameinitgen; i++ { s := lookupN("init.", i) - fn := ir.AsNode(s.Def).Name.Defn + fn := ir.AsNode(s.Def).Name().Defn // Skip init functions with empty bodies. - if fn.Nbody.Len() == 1 && fn.Nbody.First().Op == ir.OEMPTY { + if fn.Body().Len() == 1 && fn.Body().First().Op() == ir.OEMPTY { continue } fns = append(fns, s.Linksym()) @@ -91,7 +91,7 @@ func fninit(n []*ir.Node) { // Make an .inittask structure. sym := lookup(".inittask") nn := NewName(sym) - nn.Type = types.Types[types.TUINT8] // fake type + nn.SetType(types.Types[types.TUINT8]) // fake type nn.SetClass(ir.PEXTERN) sym.Def = ir.AsTypesNode(nn) exportsym(nn) diff --git a/src/cmd/compile/internal/gc/initorder.go b/src/cmd/compile/internal/gc/initorder.go index 62294b5a90..71da72f0cf 100644 --- a/src/cmd/compile/internal/gc/initorder.go +++ b/src/cmd/compile/internal/gc/initorder.go @@ -86,7 +86,7 @@ func initOrder(l []*ir.Node) []*ir.Node { // Process all package-level assignment in declaration order. for _, n := range l { - switch n.Op { + switch n.Op() { case ir.OAS, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV: o.processAssign(n) o.flushReady(s.staticInit) @@ -100,7 +100,7 @@ func initOrder(l []*ir.Node) []*ir.Node { // Check that all assignments are now Done; if not, there must // have been a dependency cycle. for _, n := range l { - switch n.Op { + switch n.Op() { case ir.OAS, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV: if n.Initorder() != InitDone { // If there have already been errors @@ -126,27 +126,27 @@ func initOrder(l []*ir.Node) []*ir.Node { } func (o *InitOrder) processAssign(n *ir.Node) { - if n.Initorder() != InitNotStarted || n.Xoffset != types.BADWIDTH { - base.Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Xoffset) + if n.Initorder() != InitNotStarted || n.Offset() != types.BADWIDTH { + base.Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Offset()) } n.SetInitorder(InitPending) - n.Xoffset = 0 + n.SetOffset(0) // Compute number of variable dependencies and build the // inverse dependency ("blocking") graph. for dep := range collectDeps(n, true) { - defn := dep.Name.Defn + defn := dep.Name().Defn // Skip dependencies on functions (PFUNC) and // variables already initialized (InitDone). if dep.Class() != ir.PEXTERN || defn.Initorder() == InitDone { continue } - n.Xoffset = n.Xoffset + 1 + n.SetOffset(n.Offset() + 1) o.blocking[defn] = append(o.blocking[defn], n) } - if n.Xoffset == 0 { + if n.Offset() == 0 { heap.Push(&o.ready, n) } } @@ -157,20 +157,20 @@ func (o *InitOrder) processAssign(n *ir.Node) { func (o *InitOrder) flushReady(initialize func(*ir.Node)) { for o.ready.Len() != 0 { n := heap.Pop(&o.ready).(*ir.Node) - if n.Initorder() != InitPending || n.Xoffset != 0 { - base.Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Xoffset) + if n.Initorder() != InitPending || n.Offset() != 0 { + base.Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Offset()) } initialize(n) n.SetInitorder(InitDone) - n.Xoffset = types.BADWIDTH + n.SetOffset(types.BADWIDTH) blocked := o.blocking[n] delete(o.blocking, n) for _, m := range blocked { - m.Xoffset = m.Xoffset - 1 - if m.Xoffset == 0 { + m.SetOffset(m.Offset() - 1) + if m.Offset() == 0 { heap.Push(&o.ready, m) } } @@ -196,14 +196,14 @@ func findInitLoopAndExit(n *ir.Node, path *[]*ir.Node) { // There might be multiple loops involving n; by sorting // references, we deterministically pick the one reported. - refers := collectDeps(n.Name.Defn, false).Sorted(func(ni, nj *ir.Node) bool { - return ni.Pos.Before(nj.Pos) + refers := collectDeps(n.Name().Defn, false).Sorted(func(ni, nj *ir.Node) bool { + return ni.Pos().Before(nj.Pos()) }) *path = append(*path, n) for _, ref := range refers { // Short-circuit variables that were initialized. - if ref.Class() == ir.PEXTERN && ref.Name.Defn.Initorder() == InitDone { + if ref.Class() == ir.PEXTERN && ref.Name().Defn.Initorder() == InitDone { continue } @@ -220,7 +220,7 @@ func reportInitLoopAndExit(l []*ir.Node) { // the start. i := -1 for j, n := range l { - if n.Class() == ir.PEXTERN && (i == -1 || n.Pos.Before(l[i].Pos)) { + if n.Class() == ir.PEXTERN && (i == -1 || n.Pos().Before(l[i].Pos())) { i = j } } @@ -242,7 +242,7 @@ func reportInitLoopAndExit(l []*ir.Node) { } fmt.Fprintf(&msg, "\t%v: %v", ir.Line(l[0]), l[0]) - base.ErrorfAt(l[0].Pos, msg.String()) + base.ErrorfAt(l[0].Pos(), msg.String()) base.ErrorExit() } @@ -252,15 +252,15 @@ func reportInitLoopAndExit(l []*ir.Node) { // upon functions (but not variables). func collectDeps(n *ir.Node, transitive bool) ir.NodeSet { d := initDeps{transitive: transitive} - switch n.Op { + switch n.Op() { case ir.OAS: - d.inspect(n.Right) + d.inspect(n.Right()) case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV: - d.inspect(n.Right) + d.inspect(n.Right()) case ir.ODCLFUNC: - d.inspectList(n.Nbody) + d.inspectList(n.Body()) default: - base.Fatalf("unexpected Op: %v", n.Op) + base.Fatalf("unexpected Op: %v", n.Op()) } return d.seen } @@ -276,7 +276,7 @@ func (d *initDeps) inspectList(l ir.Nodes) { ir.InspectList(l, d.visit) } // visit calls foundDep on any package-level functions or variables // referenced by n, if any. func (d *initDeps) visit(n *ir.Node) bool { - switch n.Op { + switch n.Op() { case ir.OMETHEXPR: d.foundDep(methodExprName(n)) return false @@ -288,7 +288,7 @@ func (d *initDeps) visit(n *ir.Node) bool { } case ir.OCLOSURE: - d.inspectList(n.Func.Decl.Nbody) + d.inspectList(n.Func().Decl.Body()) case ir.ODOTMETH, ir.OCALLPART: d.foundDep(methodExprName(n)) @@ -308,7 +308,7 @@ func (d *initDeps) foundDep(n *ir.Node) { // Names without definitions aren't interesting as far as // initialization ordering goes. - if n.Name.Defn == nil { + if n.Name().Defn == nil { return } @@ -317,7 +317,7 @@ func (d *initDeps) foundDep(n *ir.Node) { } d.seen.Add(n) if d.transitive && n.Class() == ir.PFUNC { - d.inspectList(n.Name.Defn.Nbody) + d.inspectList(n.Name().Defn.Body()) } } @@ -330,9 +330,11 @@ func (d *initDeps) foundDep(n *ir.Node) { // but both OAS nodes use the "=" token's position as their Pos. type declOrder []*ir.Node -func (s declOrder) Len() int { return len(s) } -func (s declOrder) Less(i, j int) bool { return firstLHS(s[i]).Pos.Before(firstLHS(s[j]).Pos) } -func (s declOrder) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s declOrder) Len() int { return len(s) } +func (s declOrder) Less(i, j int) bool { + return firstLHS(s[i]).Pos().Before(firstLHS(s[j]).Pos()) +} +func (s declOrder) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s *declOrder) Push(x interface{}) { *s = append(*s, x.(*ir.Node)) } func (s *declOrder) Pop() interface{} { @@ -344,13 +346,13 @@ func (s *declOrder) Pop() interface{} { // firstLHS returns the first expression on the left-hand side of // assignment n. func firstLHS(n *ir.Node) *ir.Node { - switch n.Op { + switch n.Op() { case ir.OAS: - return n.Left + return n.Left() case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2RECV, ir.OAS2MAPR: - return n.List.First() + return n.List().First() } - base.Fatalf("unexpected Op: %v", n.Op) + base.Fatalf("unexpected Op: %v", n.Op()) return nil } diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go index f982b43fb9..f82c128265 100644 --- a/src/cmd/compile/internal/gc/inl.go +++ b/src/cmd/compile/internal/gc/inl.go @@ -56,19 +56,19 @@ const ( func fnpkg(fn *ir.Node) *types.Pkg { if ir.IsMethod(fn) { // method - rcvr := fn.Type.Recv().Type + rcvr := fn.Type().Recv().Type if rcvr.IsPtr() { rcvr = rcvr.Elem() } if rcvr.Sym == nil { - base.Fatalf("receiver with no sym: [%v] %L (%v)", fn.Sym, fn, rcvr) + base.Fatalf("receiver with no sym: [%v] %L (%v)", fn.Sym(), fn, rcvr) } return rcvr.Sym.Pkg } // non-method - return fn.Sym.Pkg + return fn.Sym().Pkg } // Lazy typechecking of imported bodies. For local functions, caninl will set ->typecheck @@ -89,12 +89,12 @@ func typecheckinl(fn *ir.Node) { } if base.Flag.LowerM > 2 || base.Debug.Export != 0 { - fmt.Printf("typecheck import [%v] %L { %#v }\n", fn.Sym, fn, ir.AsNodes(fn.Func.Inl.Body)) + fmt.Printf("typecheck import [%v] %L { %#v }\n", fn.Sym(), fn, ir.AsNodes(fn.Func().Inl.Body)) } savefn := Curfn Curfn = fn - typecheckslice(fn.Func.Inl.Body, ctxStmt) + typecheckslice(fn.Func().Inl.Body, ctxStmt) Curfn = savefn // During expandInline (which imports fn.Func.Inl.Body), @@ -102,8 +102,8 @@ func typecheckinl(fn *ir.Node) { // to fn.Func.Inl.Dcl for consistency with how local functions // behave. (Append because typecheckinl may be called multiple // times.) - fn.Func.Inl.Dcl = append(fn.Func.Inl.Dcl, fn.Func.Dcl...) - fn.Func.Dcl = nil + fn.Func().Inl.Dcl = append(fn.Func().Inl.Dcl, fn.Func().Dcl...) + fn.Func().Dcl = nil base.Pos = lno } @@ -112,10 +112,10 @@ func typecheckinl(fn *ir.Node) { // If so, caninl saves fn->nbody in fn->inl and substitutes it with a copy. // fn and ->nbody will already have been typechecked. func caninl(fn *ir.Node) { - if fn.Op != ir.ODCLFUNC { + if fn.Op() != ir.ODCLFUNC { base.Fatalf("caninl %v", fn) } - if fn.Func.Nname == nil { + if fn.Func().Nname == nil { base.Fatalf("caninl no nname %+v", fn) } @@ -124,43 +124,43 @@ func caninl(fn *ir.Node) { defer func() { if reason != "" { if base.Flag.LowerM > 1 { - fmt.Printf("%v: cannot inline %v: %s\n", ir.Line(fn), fn.Func.Nname, reason) + fmt.Printf("%v: cannot inline %v: %s\n", ir.Line(fn), fn.Func().Nname, reason) } if logopt.Enabled() { - logopt.LogOpt(fn.Pos, "cannotInlineFunction", "inline", ir.FuncName(fn), reason) + logopt.LogOpt(fn.Pos(), "cannotInlineFunction", "inline", ir.FuncName(fn), reason) } } }() } // If marked "go:noinline", don't inline - if fn.Func.Pragma&ir.Noinline != 0 { + if fn.Func().Pragma&ir.Noinline != 0 { reason = "marked go:noinline" return } // If marked "go:norace" and -race compilation, don't inline. - if base.Flag.Race && fn.Func.Pragma&ir.Norace != 0 { + if base.Flag.Race && fn.Func().Pragma&ir.Norace != 0 { reason = "marked go:norace with -race compilation" return } // If marked "go:nocheckptr" and -d checkptr compilation, don't inline. - if base.Debug.Checkptr != 0 && fn.Func.Pragma&ir.NoCheckPtr != 0 { + if base.Debug.Checkptr != 0 && fn.Func().Pragma&ir.NoCheckPtr != 0 { reason = "marked go:nocheckptr" return } // If marked "go:cgo_unsafe_args", don't inline, since the // function makes assumptions about its argument frame layout. - if fn.Func.Pragma&ir.CgoUnsafeArgs != 0 { + if fn.Func().Pragma&ir.CgoUnsafeArgs != 0 { reason = "marked go:cgo_unsafe_args" return } // If marked as "go:uintptrescapes", don't inline, since the // escape information is lost during inlining. - if fn.Func.Pragma&ir.UintptrEscapes != 0 { + if fn.Func().Pragma&ir.UintptrEscapes != 0 { reason = "marked as having an escaping uintptr argument" return } @@ -169,13 +169,13 @@ func caninl(fn *ir.Node) { // granularity, so inlining yeswritebarrierrec functions can // confuse it (#22342). As a workaround, disallow inlining // them for now. - if fn.Func.Pragma&ir.Yeswritebarrierrec != 0 { + if fn.Func().Pragma&ir.Yeswritebarrierrec != 0 { reason = "marked go:yeswritebarrierrec" return } // If fn has no body (is defined outside of Go), cannot inline it. - if fn.Nbody.Len() == 0 { + if fn.Body().Len() == 0 { reason = "no function body" return } @@ -184,11 +184,11 @@ func caninl(fn *ir.Node) { base.Fatalf("caninl on non-typechecked function %v", fn) } - n := fn.Func.Nname - if n.Func.InlinabilityChecked() { + n := fn.Func().Nname + if n.Func().InlinabilityChecked() { return } - defer n.Func.SetInlinabilityChecked(true) + defer n.Func().SetInlinabilityChecked(true) cc := int32(inlineExtraCallCost) if base.Flag.LowerL == 4 { @@ -209,7 +209,7 @@ func caninl(fn *ir.Node) { extraCallCost: cc, usedLocals: make(map[*ir.Node]bool), } - if visitor.visitList(fn.Nbody) { + if visitor.visitList(fn.Body()) { reason = visitor.reason return } @@ -218,19 +218,19 @@ func caninl(fn *ir.Node) { return } - n.Func.Inl = &ir.Inline{ + n.Func().Inl = &ir.Inline{ Cost: inlineMaxBudget - visitor.budget, - Dcl: inlcopylist(pruneUnusedAutos(n.Name.Defn.Func.Dcl, &visitor)), - Body: inlcopylist(fn.Nbody.Slice()), + Dcl: inlcopylist(pruneUnusedAutos(n.Name().Defn.Func().Dcl, &visitor)), + Body: inlcopylist(fn.Body().Slice()), } if base.Flag.LowerM > 1 { - fmt.Printf("%v: can inline %#v with cost %d as: %#v { %#v }\n", ir.Line(fn), n, inlineMaxBudget-visitor.budget, fn.Type, ir.AsNodes(n.Func.Inl.Body)) + fmt.Printf("%v: can inline %#v with cost %d as: %#v { %#v }\n", ir.Line(fn), n, inlineMaxBudget-visitor.budget, fn.Type(), ir.AsNodes(n.Func().Inl.Body)) } else if base.Flag.LowerM != 0 { fmt.Printf("%v: can inline %v\n", ir.Line(fn), n) } if logopt.Enabled() { - logopt.LogOpt(fn.Pos, "canInlineFunction", "inline", ir.FuncName(fn), fmt.Sprintf("cost: %d", inlineMaxBudget-visitor.budget)) + logopt.LogOpt(fn.Pos(), "canInlineFunction", "inline", ir.FuncName(fn), fmt.Sprintf("cost: %d", inlineMaxBudget-visitor.budget)) } } @@ -240,28 +240,28 @@ func inlFlood(n *ir.Node) { if n == nil { return } - if n.Op != ir.ONAME || n.Class() != ir.PFUNC { - base.Fatalf("inlFlood: unexpected %v, %v, %v", n, n.Op, n.Class()) + if n.Op() != ir.ONAME || n.Class() != ir.PFUNC { + base.Fatalf("inlFlood: unexpected %v, %v, %v", n, n.Op(), n.Class()) } - if n.Func == nil { + if n.Func() == nil { base.Fatalf("inlFlood: missing Func on %v", n) } - if n.Func.Inl == nil { + if n.Func().Inl == nil { return } - if n.Func.ExportInline() { + if n.Func().ExportInline() { return } - n.Func.SetExportInline(true) + n.Func().SetExportInline(true) typecheckinl(n) // Recursively identify all referenced functions for // reexport. We want to include even non-called functions, // because after inlining they might be callable. - ir.InspectList(ir.AsNodes(n.Func.Inl.Body), func(n *ir.Node) bool { - switch n.Op { + ir.InspectList(ir.AsNodes(n.Func().Inl.Body), func(n *ir.Node) bool { + switch n.Op() { case ir.OMETHEXPR: inlFlood(methodExprName(n)) @@ -318,15 +318,15 @@ func (v *hairyVisitor) visit(n *ir.Node) bool { return false } - switch n.Op { + switch n.Op() { // Call is okay if inlinable and we have the budget for the body. case ir.OCALLFUNC: // Functions that call runtime.getcaller{pc,sp} can not be inlined // because getcaller{pc,sp} expect a pointer to the caller's first argument. // // runtime.throw is a "cheap call" like panic in normal code. - if n.Left.Op == ir.ONAME && n.Left.Class() == ir.PFUNC && isRuntimePkg(n.Left.Sym.Pkg) { - fn := n.Left.Sym.Name + if n.Left().Op() == ir.ONAME && n.Left().Class() == ir.PFUNC && isRuntimePkg(n.Left().Sym().Pkg) { + fn := n.Left().Sym().Name if fn == "getcallerpc" || fn == "getcallersp" { v.reason = "call to " + fn return true @@ -342,8 +342,8 @@ func (v *hairyVisitor) visit(n *ir.Node) bool { break } - if fn := inlCallee(n.Left); fn != nil && fn.Func.Inl != nil { - v.budget -= fn.Func.Inl.Cost + if fn := inlCallee(n.Left()); fn != nil && fn.Func().Inl != nil { + v.budget -= fn.Func().Inl.Cost break } @@ -352,12 +352,12 @@ func (v *hairyVisitor) visit(n *ir.Node) bool { // Call is okay if inlinable and we have the budget for the body. case ir.OCALLMETH: - t := n.Left.Type + t := n.Left().Type() if t == nil { - base.Fatalf("no function type for [%p] %+v\n", n.Left, n.Left) + base.Fatalf("no function type for [%p] %+v\n", n.Left(), n.Left()) } - if isRuntimePkg(n.Left.Sym.Pkg) { - fn := n.Left.Sym.Name + if isRuntimePkg(n.Left().Sym().Pkg) { + fn := n.Left().Sym().Name if fn == "heapBits.nextArena" { // Special case: explicitly allow // mid-stack inlining of @@ -367,7 +367,7 @@ func (v *hairyVisitor) visit(n *ir.Node) bool { break } } - if inlfn := methodExprName(n.Left).Func; inlfn.Inl != nil { + if inlfn := methodExprName(n.Left()).Func(); inlfn.Inl != nil { v.budget -= inlfn.Inl.Cost break } @@ -395,7 +395,7 @@ func (v *hairyVisitor) visit(n *ir.Node) bool { ir.ODEFER, ir.ODCLTYPE, // can't print yet ir.ORETJMP: - v.reason = "unhandled op " + n.Op.String() + v.reason = "unhandled op " + n.Op().String() return true case ir.OAPPEND: @@ -413,16 +413,16 @@ func (v *hairyVisitor) visit(n *ir.Node) bool { } case ir.OBREAK, ir.OCONTINUE: - if n.Sym != nil { + if n.Sym() != nil { // Should have short-circuited due to labeledControl above. base.Fatalf("unexpected labeled break/continue: %v", n) } case ir.OIF: - if ir.IsConst(n.Left, constant.Bool) { + if ir.IsConst(n.Left(), constant.Bool) { // This if and the condition cost nothing. - return v.visitList(n.Ninit) || v.visitList(n.Nbody) || - v.visitList(n.Rlist) + return v.visitList(n.Init()) || v.visitList(n.Body()) || + v.visitList(n.Rlist()) } case ir.ONAME: @@ -439,9 +439,9 @@ func (v *hairyVisitor) visit(n *ir.Node) bool { return true } - return v.visit(n.Left) || v.visit(n.Right) || - v.visitList(n.List) || v.visitList(n.Rlist) || - v.visitList(n.Ninit) || v.visitList(n.Nbody) + return v.visit(n.Left()) || v.visit(n.Right()) || + v.visitList(n.List()) || v.visitList(n.Rlist()) || + v.visitList(n.Init()) || v.visitList(n.Body()) } // inlcopylist (together with inlcopy) recursively copies a list of nodes, except @@ -460,21 +460,21 @@ func inlcopy(n *ir.Node) *ir.Node { return nil } - switch n.Op { + switch n.Op() { case ir.ONAME, ir.OTYPE, ir.OLITERAL, ir.ONIL: return n } m := ir.Copy(n) - if n.Op != ir.OCALLPART && m.Func != nil { + if n.Op() != ir.OCALLPART && m.Func() != nil { base.Fatalf("unexpected Func: %v", m) } - m.Left = inlcopy(n.Left) - m.Right = inlcopy(n.Right) - m.List.Set(inlcopylist(n.List.Slice())) - m.Rlist.Set(inlcopylist(n.Rlist.Slice())) - m.Ninit.Set(inlcopylist(n.Ninit.Slice())) - m.Nbody.Set(inlcopylist(n.Nbody.Slice())) + m.SetLeft(inlcopy(n.Left())) + m.SetRight(inlcopy(n.Right())) + m.PtrList().Set(inlcopylist(n.List().Slice())) + m.PtrRlist().Set(inlcopylist(n.Rlist().Slice())) + m.PtrInit().Set(inlcopylist(n.Init().Slice())) + m.PtrBody().Set(inlcopylist(n.Body().Slice())) return m } @@ -484,18 +484,18 @@ func countNodes(n *ir.Node) int { return 0 } cnt := 1 - cnt += countNodes(n.Left) - cnt += countNodes(n.Right) - for _, n1 := range n.Ninit.Slice() { + cnt += countNodes(n.Left()) + cnt += countNodes(n.Right()) + for _, n1 := range n.Init().Slice() { cnt += countNodes(n1) } - for _, n1 := range n.Nbody.Slice() { + for _, n1 := range n.Body().Slice() { cnt += countNodes(n1) } - for _, n1 := range n.List.Slice() { + for _, n1 := range n.List().Slice() { cnt += countNodes(n1) } - for _, n1 := range n.Rlist.Slice() { + for _, n1 := range n.Rlist().Slice() { cnt += countNodes(n1) } return cnt @@ -526,21 +526,21 @@ func inlcalls(fn *ir.Node) { // Turn an OINLCALL into a statement. func inlconv2stmt(n *ir.Node) { - n.Op = ir.OBLOCK + n.SetOp(ir.OBLOCK) // n->ninit stays - n.List.Set(n.Nbody.Slice()) + n.PtrList().Set(n.Body().Slice()) - n.Nbody.Set(nil) - n.Rlist.Set(nil) + n.PtrBody().Set(nil) + n.PtrRlist().Set(nil) } // Turn an OINLCALL into a single valued expression. // The result of inlconv2expr MUST be assigned back to n, e.g. // n.Left = inlconv2expr(n.Left) func inlconv2expr(n *ir.Node) *ir.Node { - r := n.Rlist.First() - return addinit(r, append(n.Ninit.Slice(), n.Nbody.Slice()...)) + r := n.Rlist().First() + return addinit(r, append(n.Init().Slice(), n.Body().Slice()...)) } // Turn the rlist (with the return values) of the OINLCALL in @@ -549,12 +549,12 @@ func inlconv2expr(n *ir.Node) *ir.Node { // order will be preserved Used in return, oas2func and call // statements. func inlconv2list(n *ir.Node) []*ir.Node { - if n.Op != ir.OINLCALL || n.Rlist.Len() == 0 { + if n.Op() != ir.OINLCALL || n.Rlist().Len() == 0 { base.Fatalf("inlconv2list %+v\n", n) } - s := n.Rlist.Slice() - s[0] = addinit(s[0], append(n.Ninit.Slice(), n.Nbody.Slice()...)) + s := n.Rlist().Slice() + s[0] = addinit(s[0], append(n.Init().Slice(), n.Body().Slice()...)) return s } @@ -583,11 +583,11 @@ func inlnode(n *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node { return n } - switch n.Op { + switch n.Op() { case ir.ODEFER, ir.OGO: - switch n.Left.Op { + switch n.Left().Op() { case ir.OCALLFUNC, ir.OCALLMETH: - n.Left.SetNoInline(true) + n.Left().SetNoInline(true) } // TODO do them here (or earlier), @@ -597,61 +597,61 @@ func inlnode(n *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node { case ir.OCALLMETH: // Prevent inlining some reflect.Value methods when using checkptr, // even when package reflect was compiled without it (#35073). - if s := n.Left.Sym; base.Debug.Checkptr != 0 && isReflectPkg(s.Pkg) && (s.Name == "Value.UnsafeAddr" || s.Name == "Value.Pointer") { + if s := n.Left().Sym(); base.Debug.Checkptr != 0 && isReflectPkg(s.Pkg) && (s.Name == "Value.UnsafeAddr" || s.Name == "Value.Pointer") { return n } } lno := setlineno(n) - inlnodelist(n.Ninit, maxCost, inlMap) - for _, n1 := range n.Ninit.Slice() { - if n1.Op == ir.OINLCALL { + inlnodelist(n.Init(), maxCost, inlMap) + for _, n1 := range n.Init().Slice() { + if n1.Op() == ir.OINLCALL { inlconv2stmt(n1) } } - n.Left = inlnode(n.Left, maxCost, inlMap) - if n.Left != nil && n.Left.Op == ir.OINLCALL { - n.Left = inlconv2expr(n.Left) + n.SetLeft(inlnode(n.Left(), maxCost, inlMap)) + if n.Left() != nil && n.Left().Op() == ir.OINLCALL { + n.SetLeft(inlconv2expr(n.Left())) } - n.Right = inlnode(n.Right, maxCost, inlMap) - if n.Right != nil && n.Right.Op == ir.OINLCALL { - if n.Op == ir.OFOR || n.Op == ir.OFORUNTIL { - inlconv2stmt(n.Right) - } else if n.Op == ir.OAS2FUNC { - n.Rlist.Set(inlconv2list(n.Right)) - n.Right = nil - n.Op = ir.OAS2 + n.SetRight(inlnode(n.Right(), maxCost, inlMap)) + if n.Right() != nil && n.Right().Op() == ir.OINLCALL { + if n.Op() == ir.OFOR || n.Op() == ir.OFORUNTIL { + inlconv2stmt(n.Right()) + } else if n.Op() == ir.OAS2FUNC { + n.PtrRlist().Set(inlconv2list(n.Right())) + n.SetRight(nil) + n.SetOp(ir.OAS2) n.SetTypecheck(0) n = typecheck(n, ctxStmt) } else { - n.Right = inlconv2expr(n.Right) + n.SetRight(inlconv2expr(n.Right())) } } - inlnodelist(n.List, maxCost, inlMap) - if n.Op == ir.OBLOCK { - for _, n2 := range n.List.Slice() { - if n2.Op == ir.OINLCALL { + inlnodelist(n.List(), maxCost, inlMap) + if n.Op() == ir.OBLOCK { + for _, n2 := range n.List().Slice() { + if n2.Op() == ir.OINLCALL { inlconv2stmt(n2) } } } else { - s := n.List.Slice() + s := n.List().Slice() for i1, n1 := range s { - if n1 != nil && n1.Op == ir.OINLCALL { + if n1 != nil && n1.Op() == ir.OINLCALL { s[i1] = inlconv2expr(s[i1]) } } } - inlnodelist(n.Rlist, maxCost, inlMap) - s := n.Rlist.Slice() + inlnodelist(n.Rlist(), maxCost, inlMap) + s := n.Rlist().Slice() for i1, n1 := range s { - if n1.Op == ir.OINLCALL { - if n.Op == ir.OIF { + if n1.Op() == ir.OINLCALL { + if n.Op() == ir.OIF { inlconv2stmt(n1) } else { s[i1] = inlconv2expr(s[i1]) @@ -659,9 +659,9 @@ func inlnode(n *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node { } } - inlnodelist(n.Nbody, maxCost, inlMap) - for _, n := range n.Nbody.Slice() { - if n.Op == ir.OINLCALL { + inlnodelist(n.Body(), maxCost, inlMap) + for _, n := range n.Body().Slice() { + if n.Op() == ir.OINLCALL { inlconv2stmt(n) } } @@ -669,36 +669,36 @@ func inlnode(n *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node { // with all the branches out of the way, it is now time to // transmogrify this node itself unless inhibited by the // switch at the top of this function. - switch n.Op { + switch n.Op() { case ir.OCALLFUNC, ir.OCALLMETH: if n.NoInline() { return n } } - switch n.Op { + switch n.Op() { case ir.OCALLFUNC: if base.Flag.LowerM > 3 { - fmt.Printf("%v:call to func %+v\n", ir.Line(n), n.Left) + fmt.Printf("%v:call to func %+v\n", ir.Line(n), n.Left()) } if isIntrinsicCall(n) { break } - if fn := inlCallee(n.Left); fn != nil && fn.Func.Inl != nil { + if fn := inlCallee(n.Left()); fn != nil && fn.Func().Inl != nil { n = mkinlcall(n, fn, maxCost, inlMap) } case ir.OCALLMETH: if base.Flag.LowerM > 3 { - fmt.Printf("%v:call to meth %L\n", ir.Line(n), n.Left.Right) + fmt.Printf("%v:call to meth %L\n", ir.Line(n), n.Left().Right()) } // typecheck should have resolved ODOTMETH->type, whose nname points to the actual function. - if n.Left.Type == nil { - base.Fatalf("no function type for [%p] %+v\n", n.Left, n.Left) + if n.Left().Type() == nil { + base.Fatalf("no function type for [%p] %+v\n", n.Left(), n.Left()) } - n = mkinlcall(n, methodExprName(n.Left), maxCost, inlMap) + n = mkinlcall(n, methodExprName(n.Left()), maxCost, inlMap) } base.Pos = lno @@ -710,29 +710,29 @@ func inlnode(n *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node { func inlCallee(fn *ir.Node) *ir.Node { fn = staticValue(fn) switch { - case fn.Op == ir.OMETHEXPR: + case fn.Op() == ir.OMETHEXPR: n := methodExprName(fn) // Check that receiver type matches fn.Left. // TODO(mdempsky): Handle implicit dereference // of pointer receiver argument? - if n == nil || !types.Identical(n.Type.Recv().Type, fn.Left.Type) { + if n == nil || !types.Identical(n.Type().Recv().Type, fn.Left().Type()) { return nil } return n - case fn.Op == ir.ONAME && fn.Class() == ir.PFUNC: + case fn.Op() == ir.ONAME && fn.Class() == ir.PFUNC: return fn - case fn.Op == ir.OCLOSURE: - c := fn.Func.Decl + case fn.Op() == ir.OCLOSURE: + c := fn.Func().Decl caninl(c) - return c.Func.Nname + return c.Func().Nname } return nil } func staticValue(n *ir.Node) *ir.Node { for { - if n.Op == ir.OCONVNOP { - n = n.Left + if n.Op() == ir.OCONVNOP { + n = n.Left() continue } @@ -748,24 +748,24 @@ func staticValue(n *ir.Node) *ir.Node { // that is initialized and never reassigned, staticValue1 returns the initializer // expression. Otherwise, it returns nil. func staticValue1(n *ir.Node) *ir.Node { - if n.Op != ir.ONAME || n.Class() != ir.PAUTO || n.Name.Addrtaken() { + if n.Op() != ir.ONAME || n.Class() != ir.PAUTO || n.Name().Addrtaken() { return nil } - defn := n.Name.Defn + defn := n.Name().Defn if defn == nil { return nil } var rhs *ir.Node FindRHS: - switch defn.Op { + switch defn.Op() { case ir.OAS: - rhs = defn.Right + rhs = defn.Right() case ir.OAS2: - for i, lhs := range defn.List.Slice() { + for i, lhs := range defn.List().Slice() { if lhs == n { - rhs = defn.Rlist.Index(i) + rhs = defn.Rlist().Index(i) break FindRHS } } @@ -792,24 +792,24 @@ FindRHS: // NB: global variables are always considered to be re-assigned. // TODO: handle initial declaration not including an assignment and followed by a single assignment? func reassigned(n *ir.Node) (bool, *ir.Node) { - if n.Op != ir.ONAME { + if n.Op() != ir.ONAME { base.Fatalf("reassigned %v", n) } // no way to reliably check for no-reassignment of globals, assume it can be - if n.Name.Curfn == nil { + if n.Name().Curfn == nil { return true, nil } - f := n.Name.Curfn + f := n.Name().Curfn // There just might be a good reason for this although this can be pretty surprising: // local variables inside a closure have Curfn pointing to the OCLOSURE node instead // of the corresponding ODCLFUNC. // We need to walk the function body to check for reassignments so we follow the // linkage to the ODCLFUNC node as that is where body is held. - if f.Op == ir.OCLOSURE { - f = f.Func.Decl + if f.Op() == ir.OCLOSURE { + f = f.Func().Decl } v := reassignVisitor{name: n} - a := v.visitList(f.Nbody) + a := v.visitList(f.Body()) return a != nil, a } @@ -821,34 +821,34 @@ func (v *reassignVisitor) visit(n *ir.Node) *ir.Node { if n == nil { return nil } - switch n.Op { + switch n.Op() { case ir.OAS: - if n.Left == v.name && n != v.name.Name.Defn { + if n.Left() == v.name && n != v.name.Name().Defn { return n } case ir.OAS2, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2DOTTYPE: - for _, p := range n.List.Slice() { - if p == v.name && n != v.name.Name.Defn { + for _, p := range n.List().Slice() { + if p == v.name && n != v.name.Name().Defn { return n } } } - if a := v.visit(n.Left); a != nil { + if a := v.visit(n.Left()); a != nil { return a } - if a := v.visit(n.Right); a != nil { + if a := v.visit(n.Right()); a != nil { return a } - if a := v.visitList(n.List); a != nil { + if a := v.visitList(n.List()); a != nil { return a } - if a := v.visitList(n.Rlist); a != nil { + if a := v.visitList(n.Rlist()); a != nil { return a } - if a := v.visitList(n.Ninit); a != nil { + if a := v.visitList(n.Init()); a != nil { return a } - if a := v.visitList(n.Nbody); a != nil { + if a := v.visitList(n.Body()); a != nil { return a } return nil @@ -873,8 +873,8 @@ func inlParam(t *types.Field, as *ir.Node, inlvars map[*ir.Node]*ir.Node) *ir.No if inlvar == nil { base.Fatalf("missing inlvar for %v", n) } - as.Ninit.Append(ir.Nod(ir.ODCL, inlvar, nil)) - inlvar.Name.Defn = as + as.PtrInit().Append(ir.Nod(ir.ODCL, inlvar, nil)) + inlvar.Name().Defn = as return inlvar } @@ -888,32 +888,32 @@ var inlgen int // The result of mkinlcall MUST be assigned back to n, e.g. // n.Left = mkinlcall(n.Left, fn, isddd) func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node { - if fn.Func.Inl == nil { + if fn.Func().Inl == nil { if logopt.Enabled() { - logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", ir.FuncName(Curfn), + logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(Curfn), fmt.Sprintf("%s cannot be inlined", ir.PkgFuncName(fn))) } return n } - if fn.Func.Inl.Cost > maxCost { + if fn.Func().Inl.Cost > maxCost { // The inlined function body is too big. Typically we use this check to restrict // inlining into very big functions. See issue 26546 and 17566. if logopt.Enabled() { - logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", ir.FuncName(Curfn), - fmt.Sprintf("cost %d of %s exceeds max large caller cost %d", fn.Func.Inl.Cost, ir.PkgFuncName(fn), maxCost)) + logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(Curfn), + fmt.Sprintf("cost %d of %s exceeds max large caller cost %d", fn.Func().Inl.Cost, ir.PkgFuncName(fn), maxCost)) } return n } - if fn == Curfn || fn.Name.Defn == Curfn { + if fn == Curfn || fn.Name().Defn == Curfn { // Can't recursively inline a function into itself. if logopt.Enabled() { - logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", fmt.Sprintf("recursive call to %s", ir.FuncName(Curfn))) + logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to %s", ir.FuncName(Curfn))) } return n } - if instrumenting && isRuntimePkg(fn.Sym.Pkg) { + if instrumenting && isRuntimePkg(fn.Sym().Pkg) { // Runtime package must not be instrumented. // Instrument skips runtime package. However, some runtime code can be // inlined into other packages and instrumented there. To avoid this, @@ -939,7 +939,7 @@ func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node // We have a function node, and it has an inlineable body. if base.Flag.LowerM > 1 { - fmt.Printf("%v: inlining call to %v %#v { %#v }\n", ir.Line(n), fn.Sym, fn.Type, ir.AsNodes(fn.Func.Inl.Body)) + fmt.Printf("%v: inlining call to %v %#v { %#v }\n", ir.Line(n), fn.Sym(), fn.Type(), ir.AsNodes(fn.Func().Inl.Body)) } else if base.Flag.LowerM != 0 { fmt.Printf("%v: inlining call to %v\n", ir.Line(n), fn) } @@ -951,19 +951,19 @@ func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node ssaDumpInlined = append(ssaDumpInlined, fn) } - ninit := n.Ninit + ninit := n.Init() // For normal function calls, the function callee expression // may contain side effects (e.g., added by addinit during // inlconv2expr or inlconv2list). Make sure to preserve these, // if necessary (#42703). - if n.Op == ir.OCALLFUNC { - callee := n.Left - for callee.Op == ir.OCONVNOP { - ninit.AppendNodes(&callee.Ninit) - callee = callee.Left + if n.Op() == ir.OCALLFUNC { + callee := n.Left() + for callee.Op() == ir.OCONVNOP { + ninit.AppendNodes(callee.PtrInit()) + callee = callee.Left() } - if callee.Op != ir.ONAME && callee.Op != ir.OCLOSURE && callee.Op != ir.OMETHEXPR { + if callee.Op() != ir.ONAME && callee.Op() != ir.OCLOSURE && callee.Op() != ir.OMETHEXPR { base.Fatalf("unexpected callee expression: %v", callee) } } @@ -975,30 +975,30 @@ func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node var inlfvars []*ir.Node // Handle captured variables when inlining closures. - if fn.Name.Defn != nil { - if c := fn.Name.Defn.Func.OClosure; c != nil { - for _, v := range c.Func.ClosureVars.Slice() { - if v.Op == ir.OXXX { + if fn.Name().Defn != nil { + if c := fn.Name().Defn.Func().OClosure; c != nil { + for _, v := range c.Func().ClosureVars.Slice() { + if v.Op() == ir.OXXX { continue } - o := v.Name.Param.Outer + o := v.Name().Param.Outer // make sure the outer param matches the inlining location // NB: if we enabled inlining of functions containing OCLOSURE or refined // the reassigned check via some sort of copy propagation this would most // likely need to be changed to a loop to walk up to the correct Param - if o == nil || (o.Name.Curfn != Curfn && o.Name.Curfn.Func.OClosure != Curfn) { + if o == nil || (o.Name().Curfn != Curfn && o.Name().Curfn.Func().OClosure != Curfn) { base.Fatalf("%v: unresolvable capture %v %v\n", ir.Line(n), fn, v) } - if v.Name.Byval() { + if v.Name().Byval() { iv := typecheck(inlvar(v), ctxExpr) ninit.Append(ir.Nod(ir.ODCL, iv, nil)) ninit.Append(typecheck(ir.Nod(ir.OAS, iv, o), ctxStmt)) inlvars[v] = iv } else { - addr := NewName(lookup("&" + v.Sym.Name)) - addr.Type = types.NewPtr(v.Type) + addr := NewName(lookup("&" + v.Sym().Name)) + addr.SetType(types.NewPtr(v.Type())) ia := typecheck(inlvar(addr), ctxExpr) ninit.Append(ir.Nod(ir.ODCL, ia, nil)) ninit.Append(typecheck(ir.Nod(ir.OAS, ia, ir.Nod(ir.OADDR, o, nil)), ctxStmt)) @@ -1012,8 +1012,8 @@ func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node } } - for _, ln := range fn.Func.Inl.Dcl { - if ln.Op != ir.ONAME { + for _, ln := range fn.Func().Inl.Dcl { + if ln.Op() != ir.ONAME { continue } if ln.Class() == ir.PPARAMOUT { // return values handled below. @@ -1030,18 +1030,18 @@ func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node inlvars[ln] = inlf if base.Flag.GenDwarfInl > 0 { if ln.Class() == ir.PPARAM { - inlf.Name.SetInlFormal(true) + inlf.Name().SetInlFormal(true) } else { - inlf.Name.SetInlLocal(true) + inlf.Name().SetInlLocal(true) } - inlf.Pos = ln.Pos + inlf.SetPos(ln.Pos()) inlfvars = append(inlfvars, inlf) } } nreturns := 0 - ir.InspectList(ir.AsNodes(fn.Func.Inl.Body), func(n *ir.Node) bool { - if n != nil && n.Op == ir.ORETURN { + ir.InspectList(ir.AsNodes(fn.Func().Inl.Body), func(n *ir.Node) bool { + if n != nil && n.Op() == ir.ORETURN { nreturns++ } return true @@ -1054,9 +1054,9 @@ func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node // temporaries for return values. var retvars []*ir.Node - for i, t := range fn.Type.Results().Fields().Slice() { + for i, t := range fn.Type().Results().Fields().Slice() { var m *ir.Node - if n := ir.AsNode(t.Nname); n != nil && !ir.IsBlank(n) && !strings.HasPrefix(n.Sym.Name, "~r") { + if n := ir.AsNode(t.Nname); n != nil && !ir.IsBlank(n) && !strings.HasPrefix(n.Sym().Name, "~r") { m = inlvar(n) m = typecheck(m, ctxExpr) inlvars[n] = m @@ -1070,9 +1070,9 @@ func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node // Don't update the src.Pos on a return variable if it // was manufactured by the inliner (e.g. "~R2"); such vars // were not part of the original callee. - if !strings.HasPrefix(m.Sym.Name, "~R") { - m.Name.SetInlFormal(true) - m.Pos = t.Pos + if !strings.HasPrefix(m.Sym().Name, "~R") { + m.Name().SetInlFormal(true) + m.SetPos(t.Pos) inlfvars = append(inlfvars, m) } } @@ -1083,51 +1083,51 @@ func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node // Assign arguments to the parameters' temp names. as := ir.Nod(ir.OAS2, nil, nil) as.SetColas(true) - if n.Op == ir.OCALLMETH { - if n.Left.Left == nil { + if n.Op() == ir.OCALLMETH { + if n.Left().Left() == nil { base.Fatalf("method call without receiver: %+v", n) } - as.Rlist.Append(n.Left.Left) + as.PtrRlist().Append(n.Left().Left()) } - as.Rlist.Append(n.List.Slice()...) + as.PtrRlist().Append(n.List().Slice()...) // For non-dotted calls to variadic functions, we assign the // variadic parameter's temp name separately. var vas *ir.Node - if recv := fn.Type.Recv(); recv != nil { - as.List.Append(inlParam(recv, as, inlvars)) + if recv := fn.Type().Recv(); recv != nil { + as.PtrList().Append(inlParam(recv, as, inlvars)) } - for _, param := range fn.Type.Params().Fields().Slice() { + for _, param := range fn.Type().Params().Fields().Slice() { // For ordinary parameters or variadic parameters in // dotted calls, just add the variable to the // assignment list, and we're done. if !param.IsDDD() || n.IsDDD() { - as.List.Append(inlParam(param, as, inlvars)) + as.PtrList().Append(inlParam(param, as, inlvars)) continue } // Otherwise, we need to collect the remaining values // to pass as a slice. - x := as.List.Len() - for as.List.Len() < as.Rlist.Len() { - as.List.Append(argvar(param.Type, as.List.Len())) + x := as.List().Len() + for as.List().Len() < as.Rlist().Len() { + as.PtrList().Append(argvar(param.Type, as.List().Len())) } - varargs := as.List.Slice()[x:] + varargs := as.List().Slice()[x:] vas = ir.Nod(ir.OAS, nil, nil) - vas.Left = inlParam(param, vas, inlvars) + vas.SetLeft(inlParam(param, vas, inlvars)) if len(varargs) == 0 { - vas.Right = nodnil() - vas.Right.Type = param.Type + vas.SetRight(nodnil()) + vas.Right().SetType(param.Type) } else { - vas.Right = ir.Nod(ir.OCOMPLIT, nil, typenod(param.Type)) - vas.Right.List.Set(varargs) + vas.SetRight(ir.Nod(ir.OCOMPLIT, nil, typenod(param.Type))) + vas.Right().PtrList().Set(varargs) } } - if as.Rlist.Len() != 0 { + if as.Rlist().Len() != 0 { as = typecheck(as, ctxStmt) ninit.Append(as) } @@ -1152,10 +1152,10 @@ func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node inlgen++ parent := -1 - if b := base.Ctxt.PosTable.Pos(n.Pos).Base(); b != nil { + if b := base.Ctxt.PosTable.Pos(n.Pos()).Base(); b != nil { parent = b.InliningIndex() } - newIndex := base.Ctxt.InlTree.Add(parent, n.Pos, fn.Sym.Linksym()) + newIndex := base.Ctxt.InlTree.Add(parent, n.Pos(), fn.Sym().Linksym()) // Add an inline mark just before the inlined body. // This mark is inline in the code so that it's a reasonable spot @@ -1163,14 +1163,14 @@ func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node // (in which case it could go at the end of the function instead). // Note issue 28603. inlMark := ir.Nod(ir.OINLMARK, nil, nil) - inlMark.Pos = n.Pos.WithIsStmt() - inlMark.Xoffset = int64(newIndex) + inlMark.SetPos(n.Pos().WithIsStmt()) + inlMark.SetOffset(int64(newIndex)) ninit.Append(inlMark) if base.Flag.GenDwarfInl > 0 { - if !fn.Sym.Linksym().WasInlined() { - base.Ctxt.DwFixups.SetPrecursorFunc(fn.Sym.Linksym(), fn) - fn.Sym.Linksym().Set(obj.AttrWasInlined, true) + if !fn.Sym().Linksym().WasInlined() { + base.Ctxt.DwFixups.SetPrecursorFunc(fn.Sym().Linksym(), fn) + fn.Sym().Linksym().Set(obj.AttrWasInlined, true) } } @@ -1183,7 +1183,7 @@ func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node newInlIndex: newIndex, } - body := subst.list(ir.AsNodes(fn.Func.Inl.Body)) + body := subst.list(ir.AsNodes(fn.Func().Inl.Body)) lab := nodSym(ir.OLABEL, nil, retlabel) body = append(body, lab) @@ -1192,17 +1192,17 @@ func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node if base.Flag.GenDwarfInl > 0 { for _, v := range inlfvars { - v.Pos = subst.updatedPos(v.Pos) + v.SetPos(subst.updatedPos(v.Pos())) } } //dumplist("ninit post", ninit); call := ir.Nod(ir.OINLCALL, nil, nil) - call.Ninit.Set(ninit.Slice()) - call.Nbody.Set(body) - call.Rlist.Set(retvars) - call.Type = n.Type + call.PtrInit().Set(ninit.Slice()) + call.PtrBody().Set(body) + call.PtrRlist().Set(retvars) + call.SetType(n.Type()) call.SetTypecheck(1) // transitive inlining @@ -1211,9 +1211,9 @@ func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node // instead we emit the things that the body needs // and each use must redo the inlining. // luckily these are small. - inlnodelist(call.Nbody, maxCost, inlMap) - for _, n := range call.Nbody.Slice() { - if n.Op == ir.OINLCALL { + inlnodelist(call.Body(), maxCost, inlMap) + for _, n := range call.Body().Slice() { + if n.Op() == ir.OINLCALL { inlconv2stmt(n) } } @@ -1233,25 +1233,25 @@ func inlvar(var_ *ir.Node) *ir.Node { fmt.Printf("inlvar %+v\n", var_) } - n := NewName(var_.Sym) - n.Type = var_.Type + n := NewName(var_.Sym()) + n.SetType(var_.Type()) n.SetClass(ir.PAUTO) - n.Name.SetUsed(true) - n.Name.Curfn = Curfn // the calling function, not the called one - n.Name.SetAddrtaken(var_.Name.Addrtaken()) + n.Name().SetUsed(true) + n.Name().Curfn = Curfn // the calling function, not the called one + n.Name().SetAddrtaken(var_.Name().Addrtaken()) - Curfn.Func.Dcl = append(Curfn.Func.Dcl, n) + Curfn.Func().Dcl = append(Curfn.Func().Dcl, n) return n } // Synthesize a variable to store the inlined function's results in. func retvar(t *types.Field, i int) *ir.Node { n := NewName(lookupN("~R", i)) - n.Type = t.Type + n.SetType(t.Type) n.SetClass(ir.PAUTO) - n.Name.SetUsed(true) - n.Name.Curfn = Curfn // the calling function, not the called one - Curfn.Func.Dcl = append(Curfn.Func.Dcl, n) + n.Name().SetUsed(true) + n.Name().Curfn = Curfn // the calling function, not the called one + Curfn.Func().Dcl = append(Curfn.Func().Dcl, n) return n } @@ -1259,11 +1259,11 @@ func retvar(t *types.Field, i int) *ir.Node { // when they come from a multiple return call. func argvar(t *types.Type, i int) *ir.Node { n := NewName(lookupN("~arg", i)) - n.Type = t.Elem() + n.SetType(t.Elem()) n.SetClass(ir.PAUTO) - n.Name.SetUsed(true) - n.Name.Curfn = Curfn // the calling function, not the called one - Curfn.Func.Dcl = append(Curfn.Func.Dcl, n) + n.Name().SetUsed(true) + n.Name().Curfn = Curfn // the calling function, not the called one + Curfn.Func().Dcl = append(Curfn.Func().Dcl, n) return n } @@ -1309,7 +1309,7 @@ func (subst *inlsubst) node(n *ir.Node) *ir.Node { return nil } - switch n.Op { + switch n.Op() { case ir.ONAME: if inlvar := subst.inlvars[n]; inlvar != nil { // These will be set during inlnode if base.Flag.LowerM > 2 { @@ -1330,7 +1330,7 @@ func (subst *inlsubst) node(n *ir.Node) *ir.Node { // If n is a named constant or type, we can continue // using it in the inline copy. Otherwise, make a copy // so we can update the line number. - if n.Sym != nil { + if n.Sym() != nil { return n } @@ -1339,31 +1339,31 @@ func (subst *inlsubst) node(n *ir.Node) *ir.Node { // dump("Return before substitution", n); case ir.ORETURN: m := nodSym(ir.OGOTO, nil, subst.retlabel) - m.Ninit.Set(subst.list(n.Ninit)) + m.PtrInit().Set(subst.list(n.Init())) - if len(subst.retvars) != 0 && n.List.Len() != 0 { + if len(subst.retvars) != 0 && n.List().Len() != 0 { as := ir.Nod(ir.OAS2, nil, nil) // Make a shallow copy of retvars. // Otherwise OINLCALL.Rlist will be the same list, // and later walk and typecheck may clobber it. for _, n := range subst.retvars { - as.List.Append(n) + as.PtrList().Append(n) } - as.Rlist.Set(subst.list(n.List)) + as.PtrRlist().Set(subst.list(n.List())) if subst.delayretvars { - for _, n := range as.List.Slice() { - as.Ninit.Append(ir.Nod(ir.ODCL, n, nil)) - n.Name.Defn = as + for _, n := range as.List().Slice() { + as.PtrInit().Append(ir.Nod(ir.ODCL, n, nil)) + n.Name().Defn = as } } as = typecheck(as, ctxStmt) - m.Ninit.Append(as) + m.PtrInit().Append(as) } - typecheckslice(m.Ninit.Slice(), ctxStmt) + typecheckslice(m.Init().Slice(), ctxStmt) m = typecheck(m, ctxStmt) // dump("Return after substitution", m); @@ -1371,28 +1371,28 @@ func (subst *inlsubst) node(n *ir.Node) *ir.Node { case ir.OGOTO, ir.OLABEL: m := ir.Copy(n) - m.Pos = subst.updatedPos(m.Pos) - m.Ninit.Set(nil) - p := fmt.Sprintf("%s·%d", n.Sym.Name, inlgen) - m.Sym = lookup(p) + m.SetPos(subst.updatedPos(m.Pos())) + m.PtrInit().Set(nil) + p := fmt.Sprintf("%s·%d", n.Sym().Name, inlgen) + m.SetSym(lookup(p)) return m } m := ir.Copy(n) - m.Pos = subst.updatedPos(m.Pos) - m.Ninit.Set(nil) + m.SetPos(subst.updatedPos(m.Pos())) + m.PtrInit().Set(nil) - if n.Op == ir.OCLOSURE { + if n.Op() == ir.OCLOSURE { base.Fatalf("cannot inline function containing closure: %+v", n) } - m.Left = subst.node(n.Left) - m.Right = subst.node(n.Right) - m.List.Set(subst.list(n.List)) - m.Rlist.Set(subst.list(n.Rlist)) - m.Ninit.Set(append(m.Ninit.Slice(), subst.list(n.Ninit)...)) - m.Nbody.Set(subst.list(n.Nbody)) + m.SetLeft(subst.node(n.Left())) + m.SetRight(subst.node(n.Right())) + m.PtrList().Set(subst.list(n.List())) + m.PtrRlist().Set(subst.list(n.Rlist())) + m.PtrInit().Set(append(m.Init().Slice(), subst.list(n.Init())...)) + m.PtrBody().Set(subst.list(n.Body())) return m } @@ -1426,8 +1426,8 @@ func pruneUnusedAutos(ll []*ir.Node, vis *hairyVisitor) []*ir.Node { // concrete-type method calls where applicable. func devirtualize(fn *ir.Node) { Curfn = fn - ir.InspectList(fn.Nbody, func(n *ir.Node) bool { - if n.Op == ir.OCALLINTER { + ir.InspectList(fn.Body(), func(n *ir.Node) bool { + if n.Op() == ir.OCALLINTER { devirtualizeCall(n) } return true @@ -1435,38 +1435,38 @@ func devirtualize(fn *ir.Node) { } func devirtualizeCall(call *ir.Node) { - recv := staticValue(call.Left.Left) - if recv.Op != ir.OCONVIFACE { + recv := staticValue(call.Left().Left()) + if recv.Op() != ir.OCONVIFACE { return } - typ := recv.Left.Type + typ := recv.Left().Type() if typ.IsInterface() { return } - x := ir.NodAt(call.Left.Pos, ir.ODOTTYPE, call.Left.Left, nil) - x.Type = typ - x = nodlSym(call.Left.Pos, ir.OXDOT, x, call.Left.Sym) + x := ir.NodAt(call.Left().Pos(), ir.ODOTTYPE, call.Left().Left(), nil) + x.SetType(typ) + x = nodlSym(call.Left().Pos(), ir.OXDOT, x, call.Left().Sym()) x = typecheck(x, ctxExpr|ctxCallee) - switch x.Op { + switch x.Op() { case ir.ODOTMETH: if base.Flag.LowerM != 0 { - base.WarnfAt(call.Pos, "devirtualizing %v to %v", call.Left, typ) + base.WarnfAt(call.Pos(), "devirtualizing %v to %v", call.Left(), typ) } - call.Op = ir.OCALLMETH - call.Left = x + call.SetOp(ir.OCALLMETH) + call.SetLeft(x) case ir.ODOTINTER: // Promoted method from embedded interface-typed field (#42279). if base.Flag.LowerM != 0 { - base.WarnfAt(call.Pos, "partially devirtualizing %v to %v", call.Left, typ) + base.WarnfAt(call.Pos(), "partially devirtualizing %v to %v", call.Left(), typ) } - call.Op = ir.OCALLINTER - call.Left = x + call.SetOp(ir.OCALLINTER) + call.SetLeft(x) default: // TODO(mdempsky): Turn back into Fatalf after more testing. if base.Flag.LowerM != 0 { - base.WarnfAt(call.Pos, "failed to devirtualize %v (%v)", x, x.Op) + base.WarnfAt(call.Pos(), "failed to devirtualize %v (%v)", x, x.Op()) } return } @@ -1477,12 +1477,12 @@ func devirtualizeCall(call *ir.Node) { // Receiver parameter size may have changed; need to update // call.Type to get correct stack offsets for result // parameters. - checkwidth(x.Type) - switch ft := x.Type; ft.NumResults() { + checkwidth(x.Type()) + switch ft := x.Type(); ft.NumResults() { case 0: case 1: - call.Type = ft.Results().Field(0).Type + call.SetType(ft.Results().Field(0).Type) default: - call.Type = ft.Results() + call.SetType(ft.Results()) } } diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go index 24e926602b..a7d605f3ba 100644 --- a/src/cmd/compile/internal/gc/main.go +++ b/src/cmd/compile/internal/gc/main.go @@ -253,7 +253,7 @@ func Main(archInit func(*Arch)) { timings.Start("fe", "typecheck", "top1") for i := 0; i < len(xtop); i++ { n := xtop[i] - if op := n.Op; op != ir.ODCL && op != ir.OAS && op != ir.OAS2 && (op != ir.ODCLTYPE || !n.Left.Name.Param.Alias()) { + if op := n.Op(); op != ir.ODCL && op != ir.OAS && op != ir.OAS2 && (op != ir.ODCLTYPE || !n.Left().Name().Param.Alias()) { xtop[i] = typecheck(n, ctxStmt) } } @@ -265,7 +265,7 @@ func Main(archInit func(*Arch)) { timings.Start("fe", "typecheck", "top2") for i := 0; i < len(xtop); i++ { n := xtop[i] - if op := n.Op; op == ir.ODCL || op == ir.OAS || op == ir.OAS2 || op == ir.ODCLTYPE && n.Left.Name.Param.Alias() { + if op := n.Op(); op == ir.ODCL || op == ir.OAS || op == ir.OAS2 || op == ir.ODCLTYPE && n.Left().Name().Param.Alias() { xtop[i] = typecheck(n, ctxStmt) } } @@ -276,14 +276,14 @@ func Main(archInit func(*Arch)) { var fcount int64 for i := 0; i < len(xtop); i++ { n := xtop[i] - if n.Op == ir.ODCLFUNC { + if n.Op() == ir.ODCLFUNC { Curfn = n decldepth = 1 errorsBefore := base.Errors() - typecheckslice(Curfn.Nbody.Slice(), ctxStmt) + typecheckslice(Curfn.Body().Slice(), ctxStmt) checkreturn(Curfn) if base.Errors() > errorsBefore { - Curfn.Nbody.Set(nil) // type errors; do not compile + Curfn.PtrBody().Set(nil) // type errors; do not compile } // Now that we've checked whether n terminates, // we can eliminate some obviously dead code. @@ -306,7 +306,7 @@ func Main(archInit func(*Arch)) { // because variables captured by value do not escape. timings.Start("fe", "capturevars") for _, n := range xtop { - if n.Op == ir.ODCLFUNC && n.Func.OClosure != nil { + if n.Op() == ir.ODCLFUNC && n.Func().OClosure != nil { Curfn = n capturevars(n) } @@ -321,7 +321,7 @@ func Main(archInit func(*Arch)) { // Typecheck imported function bodies if Debug.l > 1, // otherwise lazily when used or re-exported. for _, n := range importlist { - if n.Func.Inl != nil { + if n.Func().Inl != nil { typecheckinl(n) } } @@ -340,7 +340,7 @@ func Main(archInit func(*Arch)) { caninl(n) } else { if base.Flag.LowerM > 1 { - fmt.Printf("%v: cannot inline %v: recursive\n", ir.Line(n), n.Func.Nname) + fmt.Printf("%v: cannot inline %v: recursive\n", ir.Line(n), n.Func().Nname) } } inlcalls(n) @@ -349,7 +349,7 @@ func Main(archInit func(*Arch)) { } for _, n := range xtop { - if n.Op == ir.ODCLFUNC { + if n.Op() == ir.ODCLFUNC { devirtualize(n) } } @@ -379,7 +379,7 @@ func Main(archInit func(*Arch)) { // before walk reaches a call of a closure. timings.Start("fe", "xclosures") for _, n := range xtop { - if n.Op == ir.ODCLFUNC && n.Func.OClosure != nil { + if n.Op() == ir.ODCLFUNC && n.Func().OClosure != nil { Curfn = n transformclosure(n) } @@ -402,7 +402,7 @@ func Main(archInit func(*Arch)) { fcount = 0 for i := 0; i < len(xtop); i++ { n := xtop[i] - if n.Op == ir.ODCLFUNC { + if n.Op() == ir.ODCLFUNC { funccompile(n) fcount++ } @@ -430,7 +430,7 @@ func Main(archInit func(*Arch)) { // Phase 9: Check external declarations. timings.Start("be", "externaldcls") for i, n := range externdcl { - if n.Op == ir.ONAME { + if n.Op() == ir.ONAME { externdcl[i] = typecheck(externdcl[i], ctxExpr) } } @@ -484,7 +484,7 @@ func Main(archInit func(*Arch)) { func numNonClosures(list []*ir.Node) int { count := 0 for _, n := range list { - if n.Func.OClosure == nil { + if n.Func().OClosure == nil { count++ } } @@ -949,14 +949,14 @@ func clearImports() { if n == nil { continue } - if n.Op == ir.OPACK { + if n.Op() == ir.OPACK { // throw away top-level package name left over // from previous file. // leave s->block set to cause redeclaration // errors if a conflicting top-level name is // introduced by a different file. - if !n.Name.Used() && base.SyntaxErrors() == 0 { - unused = append(unused, importedPkg{n.Pos, n.Name.Pkg.Path, s.Name}) + if !n.Name().Used() && base.SyntaxErrors() == 0 { + unused = append(unused, importedPkg{n.Pos(), n.Name().Pkg.Path, s.Name}) } s.Def = nil continue @@ -964,9 +964,9 @@ func clearImports() { if IsAlias(s) { // throw away top-level name left over // from previous import . "x" - if n.Name != nil && n.Name.Pack != nil && !n.Name.Pack.Name.Used() && base.SyntaxErrors() == 0 { - unused = append(unused, importedPkg{n.Name.Pack.Pos, n.Name.Pack.Name.Pkg.Path, ""}) - n.Name.Pack.Name.SetUsed(true) + if n.Name() != nil && n.Name().Pack != nil && !n.Name().Pack.Name().Used() && base.SyntaxErrors() == 0 { + unused = append(unused, importedPkg{n.Name().Pack.Pos(), n.Name().Pack.Name().Pkg.Path, ""}) + n.Name().Pack.Name().SetUsed(true) } s.Def = nil continue @@ -980,7 +980,7 @@ func clearImports() { } func IsAlias(sym *types.Sym) bool { - return sym.Def != nil && ir.AsNode(sym.Def).Sym != sym + return sym.Def != nil && ir.AsNode(sym.Def).Sym() != sym } // recordFlags records the specified command-line flags to be placed diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go index eeed3740f0..98819fadde 100644 --- a/src/cmd/compile/internal/gc/noder.go +++ b/src/cmd/compile/internal/gc/noder.go @@ -162,10 +162,10 @@ func (p *noder) funcBody(fn *ir.Node, block *syntax.BlockStmt) { if body == nil { body = []*ir.Node{ir.Nod(ir.OEMPTY, nil, nil)} } - fn.Nbody.Set(body) + fn.PtrBody().Set(body) base.Pos = p.makeXPos(block.Rbrace) - fn.Func.Endlineno = base.Pos + fn.Func().Endlineno = base.Pos } funcbody() @@ -176,9 +176,9 @@ func (p *noder) openScope(pos syntax.Pos) { types.Markdcl() if trackScopes { - Curfn.Func.Parents = append(Curfn.Func.Parents, p.scope) - p.scopeVars = append(p.scopeVars, len(Curfn.Func.Dcl)) - p.scope = ir.ScopeID(len(Curfn.Func.Parents)) + Curfn.Func().Parents = append(Curfn.Func().Parents, p.scope) + p.scopeVars = append(p.scopeVars, len(Curfn.Func().Dcl)) + p.scope = ir.ScopeID(len(Curfn.Func().Parents)) p.markScope(pos) } @@ -191,29 +191,29 @@ func (p *noder) closeScope(pos syntax.Pos) { if trackScopes { scopeVars := p.scopeVars[len(p.scopeVars)-1] p.scopeVars = p.scopeVars[:len(p.scopeVars)-1] - if scopeVars == len(Curfn.Func.Dcl) { + if scopeVars == len(Curfn.Func().Dcl) { // no variables were declared in this scope, so we can retract it. - if int(p.scope) != len(Curfn.Func.Parents) { + if int(p.scope) != len(Curfn.Func().Parents) { base.Fatalf("scope tracking inconsistency, no variables declared but scopes were not retracted") } - p.scope = Curfn.Func.Parents[p.scope-1] - Curfn.Func.Parents = Curfn.Func.Parents[:len(Curfn.Func.Parents)-1] + p.scope = Curfn.Func().Parents[p.scope-1] + Curfn.Func().Parents = Curfn.Func().Parents[:len(Curfn.Func().Parents)-1] - nmarks := len(Curfn.Func.Marks) - Curfn.Func.Marks[nmarks-1].Scope = p.scope + nmarks := len(Curfn.Func().Marks) + Curfn.Func().Marks[nmarks-1].Scope = p.scope prevScope := ir.ScopeID(0) if nmarks >= 2 { - prevScope = Curfn.Func.Marks[nmarks-2].Scope + prevScope = Curfn.Func().Marks[nmarks-2].Scope } - if Curfn.Func.Marks[nmarks-1].Scope == prevScope { - Curfn.Func.Marks = Curfn.Func.Marks[:nmarks-1] + if Curfn.Func().Marks[nmarks-1].Scope == prevScope { + Curfn.Func().Marks = Curfn.Func().Marks[:nmarks-1] } return } - p.scope = Curfn.Func.Parents[p.scope-1] + p.scope = Curfn.Func().Parents[p.scope-1] p.markScope(pos) } @@ -221,10 +221,10 @@ func (p *noder) closeScope(pos syntax.Pos) { func (p *noder) markScope(pos syntax.Pos) { xpos := p.makeXPos(pos) - if i := len(Curfn.Func.Marks); i > 0 && Curfn.Func.Marks[i-1].Pos == xpos { - Curfn.Func.Marks[i-1].Scope = p.scope + if i := len(Curfn.Func().Marks); i > 0 && Curfn.Func().Marks[i-1].Pos == xpos { + Curfn.Func().Marks[i-1].Scope = p.scope } else { - Curfn.Func.Marks = append(Curfn.Func.Marks, ir.Mark{Pos: xpos, Scope: p.scope}) + Curfn.Func().Marks = append(Curfn.Func().Marks, ir.Mark{Pos: xpos, Scope: p.scope}) } } @@ -357,24 +357,24 @@ func (p *noder) importDecl(imp *syntax.ImportDecl) { } pack := p.nod(imp, ir.OPACK, nil, nil) - pack.Sym = my - pack.Name.Pkg = ipkg + pack.SetSym(my) + pack.Name().Pkg = ipkg switch my.Name { case ".": importdot(ipkg, pack) return case "init": - base.ErrorfAt(pack.Pos, "cannot import package as init - init must be a func") + base.ErrorfAt(pack.Pos(), "cannot import package as init - init must be a func") return case "_": return } if my.Def != nil { - redeclare(pack.Pos, my, "as imported package name") + redeclare(pack.Pos(), my, "as imported package name") } my.Def = ir.AsTypesNode(pack) - my.Lastlineno = pack.Pos + my.Lastlineno = pack.Pos() my.Block = 1 // at top level } @@ -452,14 +452,14 @@ func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*ir.Node { } v := values[i] if decl.Values == nil { - v = treecopy(v, n.Pos) + v = treecopy(v, n.Pos()) } - n.Op = ir.OLITERAL + n.SetOp(ir.OLITERAL) declare(n, dclcontext) - n.Name.Param.Ntype = typ - n.Name.Defn = v + n.Name().Param.Ntype = typ + n.Name().Defn = v n.SetIota(cs.iota) nn = append(nn, p.nod(decl, ir.ODCLCONST, n, nil)) @@ -476,13 +476,13 @@ func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*ir.Node { func (p *noder) typeDecl(decl *syntax.TypeDecl) *ir.Node { n := p.declName(decl.Name) - n.Op = ir.OTYPE + n.SetOp(ir.OTYPE) declare(n, dclcontext) // decl.Type may be nil but in that case we got a syntax error during parsing typ := p.typeExprOrNil(decl.Type) - param := n.Name.Param + param := n.Name().Param param.Ntype = typ param.SetAlias(decl.Alias) if pragma, ok := decl.Pragma.(*Pragma); ok { @@ -495,7 +495,7 @@ func (p *noder) typeDecl(decl *syntax.TypeDecl) *ir.Node { nod := p.nod(decl, ir.ODCLTYPE, n, nil) if param.Alias() && !langSupported(1, 9, ir.LocalPkg) { - base.ErrorfAt(nod.Pos, "type aliases only supported as of -lang=go1.9") + base.ErrorfAt(nod.Pos(), "type aliases only supported as of -lang=go1.9") } return nod } @@ -510,7 +510,7 @@ func (p *noder) declNames(names []*syntax.Name) []*ir.Node { func (p *noder) declName(name *syntax.Name) *ir.Node { n := dclname(p.name(name)) - n.Pos = p.pos(name) + n.SetPos(p.pos(name)) return n } @@ -522,43 +522,43 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *ir.Node { if fun.Recv == nil { if name.Name == "init" { name = renameinit() - if t.List.Len() > 0 || t.Rlist.Len() > 0 { - base.ErrorfAt(f.Pos, "func init must have no arguments and no return values") + if t.List().Len() > 0 || t.Rlist().Len() > 0 { + base.ErrorfAt(f.Pos(), "func init must have no arguments and no return values") } } if ir.LocalPkg.Name == "main" && name.Name == "main" { - if t.List.Len() > 0 || t.Rlist.Len() > 0 { - base.ErrorfAt(f.Pos, "func main must have no arguments and no return values") + if t.List().Len() > 0 || t.Rlist().Len() > 0 { + base.ErrorfAt(f.Pos(), "func main must have no arguments and no return values") } } } else { - f.Func.Shortname = name - name = ir.BlankNode.Sym // filled in by typecheckfunc + f.Func().Shortname = name + name = ir.BlankNode.Sym() // filled in by typecheckfunc } - f.Func.Nname = newfuncnamel(p.pos(fun.Name), name, f.Func) - f.Func.Nname.Name.Defn = f - f.Func.Nname.Name.Param.Ntype = t + f.Func().Nname = newfuncnamel(p.pos(fun.Name), name, f.Func()) + f.Func().Nname.Name().Defn = f + f.Func().Nname.Name().Param.Ntype = t if pragma, ok := fun.Pragma.(*Pragma); ok { - f.Func.Pragma = pragma.Flag & FuncPragmas + f.Func().Pragma = pragma.Flag & FuncPragmas if pragma.Flag&ir.Systemstack != 0 && pragma.Flag&ir.Nosplit != 0 { - base.ErrorfAt(f.Pos, "go:nosplit and go:systemstack cannot be combined") + base.ErrorfAt(f.Pos(), "go:nosplit and go:systemstack cannot be combined") } pragma.Flag &^= FuncPragmas p.checkUnused(pragma) } if fun.Recv == nil { - declare(f.Func.Nname, ir.PFUNC) + declare(f.Func().Nname, ir.PFUNC) } p.funcBody(f, fun.Body) if fun.Body != nil { - if f.Func.Pragma&ir.Noescape != 0 { - base.ErrorfAt(f.Pos, "can only use //go:noescape with external func implementations") + if f.Func().Pragma&ir.Noescape != 0 { + base.ErrorfAt(f.Pos(), "can only use //go:noescape with external func implementations") } } else { if base.Flag.Complete || strings.HasPrefix(ir.FuncName(f), "init.") { @@ -572,7 +572,7 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *ir.Node { } } if !isLinknamed { - base.ErrorfAt(f.Pos, "missing function body") + base.ErrorfAt(f.Pos(), "missing function body") } } } @@ -583,10 +583,10 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *ir.Node { func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *ir.Node { n := p.nod(typ, ir.OTFUNC, nil, nil) if recv != nil { - n.Left = p.param(recv, false, false) + n.SetLeft(p.param(recv, false, false)) } - n.List.Set(p.params(typ.ParamList, true)) - n.Rlist.Set(p.params(typ.ResultList, false)) + n.PtrList().Set(p.params(typ.ParamList, true)) + n.PtrRlist().Set(p.params(typ.ResultList, false)) return n } @@ -609,7 +609,7 @@ func (p *noder) param(param *syntax.Field, dddOk, final bool) *ir.Node { n := p.nodSym(param, ir.ODCLFIELD, typ, name) // rewrite ...T parameter - if typ.Op == ir.ODDD { + if typ.Op() == ir.ODDD { if !dddOk { // We mark these as syntax errors to get automatic elimination // of multiple such errors per line (see ErrorfAt in subr.go). @@ -621,12 +621,12 @@ func (p *noder) param(param *syntax.Field, dddOk, final bool) *ir.Node { p.errorAt(param.Name.Pos(), "syntax error: cannot use ... with non-final parameter %s", param.Name.Value) } } - typ.Op = ir.OTARRAY - typ.Right = typ.Left - typ.Left = nil + typ.SetOp(ir.OTARRAY) + typ.SetRight(typ.Left()) + typ.SetLeft(nil) n.SetIsDDD(true) - if n.Left != nil { - n.Left.SetIsDDD(true) + if n.Left() != nil { + n.Left().SetIsDDD(true) } } @@ -658,20 +658,20 @@ func (p *noder) expr(expr syntax.Expr) *ir.Node { case *syntax.BasicLit: n := ir.NewLiteral(p.basicLit(expr)) if expr.Kind == syntax.RuneLit { - n.Type = types.UntypedRune + n.SetType(types.UntypedRune) } n.SetDiag(expr.Bad) // avoid follow-on errors if there was a syntax error return n case *syntax.CompositeLit: n := p.nod(expr, ir.OCOMPLIT, nil, nil) if expr.Type != nil { - n.Right = p.expr(expr.Type) + n.SetRight(p.expr(expr.Type)) } l := p.exprs(expr.ElemList) for i, e := range l { l[i] = p.wrapname(expr.ElemList[i], e) } - n.List.Set(l) + n.PtrList().Set(l) base.Pos = p.makeXPos(expr.Rbrace) return n case *syntax.KeyValueExpr: @@ -684,12 +684,12 @@ func (p *noder) expr(expr syntax.Expr) *ir.Node { case *syntax.SelectorExpr: // parser.new_dotname obj := p.expr(expr.X) - if obj.Op == ir.OPACK { - obj.Name.SetUsed(true) - return importName(obj.Name.Pkg.Lookup(expr.Sel.Value)) + if obj.Op() == ir.OPACK { + obj.Name().SetUsed(true) + return importName(obj.Name().Pkg.Lookup(expr.Sel.Value)) } n := nodSym(ir.OXDOT, obj, p.name(expr.Sel)) - n.Pos = p.pos(expr) // lineno may have been changed by p.expr(expr.X) + n.SetPos(p.pos(expr)) // lineno may have been changed by p.expr(expr.X) return n case *syntax.IndexExpr: return p.nod(expr, ir.OINDEX, p.expr(expr.X), p.expr(expr.Index)) @@ -720,7 +720,7 @@ func (p *noder) expr(expr syntax.Expr) *ir.Node { return p.nod(expr, p.binOp(expr.Op), x, p.expr(expr.Y)) case *syntax.CallExpr: n := p.nod(expr, ir.OCALL, p.expr(expr.Fun), nil) - n.List.Set(p.exprs(expr.ArgList)) + n.PtrList().Set(p.exprs(expr.ArgList)) n.SetIsDDD(expr.HasDots) return n @@ -752,9 +752,9 @@ func (p *noder) expr(expr syntax.Expr) *ir.Node { case *syntax.TypeSwitchGuard: n := p.nod(expr, ir.OTYPESW, nil, p.expr(expr.X)) if expr.Lhs != nil { - n.Left = p.declName(expr.Lhs) - if ir.IsBlank(n.Left) { - base.Errorf("invalid variable name %v in type switch", n.Left) + n.SetLeft(p.declName(expr.Lhs)) + if ir.IsBlank(n.Left()) { + base.Errorf("invalid variable name %v in type switch", n.Left()) } } return n @@ -804,7 +804,7 @@ func (p *noder) sum(x syntax.Expr) *ir.Node { chunks := make([]string, 0, 1) n := p.expr(x) - if ir.IsConst(n, constant.String) && n.Sym == nil { + if ir.IsConst(n, constant.String) && n.Sym() == nil { nstr = n chunks = append(chunks, nstr.StringVal()) } @@ -813,7 +813,7 @@ func (p *noder) sum(x syntax.Expr) *ir.Node { add := adds[i] r := p.expr(add.Y) - if ir.IsConst(r, constant.String) && r.Sym == nil { + if ir.IsConst(r, constant.String) && r.Sym() == nil { if nstr != nil { // Collapse r into nstr instead of adding to n. chunks = append(chunks, r.StringVal()) @@ -880,7 +880,7 @@ func (p *noder) structType(expr *syntax.StructType) *ir.Node { p.setlineno(expr) n := p.nod(expr, ir.OTSTRUCT, nil, nil) - n.List.Set(l) + n.PtrList().Set(l) return n } @@ -894,7 +894,7 @@ func (p *noder) interfaceType(expr *syntax.InterfaceType) *ir.Node { } else { mname := p.name(method.Name) sig := p.typeExpr(method.Type) - sig.Left = fakeRecv() + sig.SetLeft(fakeRecv()) n = p.nodSym(method, ir.ODCLFIELD, sig, mname) ifacedcl(n) } @@ -902,7 +902,7 @@ func (p *noder) interfaceType(expr *syntax.InterfaceType) *ir.Node { } n := p.nod(expr, ir.OTINTER, nil, nil) - n.List.Set(l) + n.PtrList().Set(l) return n } @@ -910,8 +910,8 @@ func (p *noder) packname(expr syntax.Expr) *types.Sym { switch expr := expr.(type) { case *syntax.Name: name := p.name(expr) - if n := oldname(name); n.Name != nil && n.Name.Pack != nil { - n.Name.Pack.Name.SetUsed(true) + if n := oldname(name); n.Name() != nil && n.Name().Pack != nil { + n.Name().Pack.Name().SetUsed(true) } return name case *syntax.SelectorExpr: @@ -922,12 +922,12 @@ func (p *noder) packname(expr syntax.Expr) *types.Sym { return name } var pkg *types.Pkg - if def.Op != ir.OPACK { + if def.Op() != ir.OPACK { base.Errorf("%v is not a package", name) pkg = ir.LocalPkg } else { - def.Name.SetUsed(true) - pkg = def.Name.Pkg + def.Name().SetUsed(true) + pkg = def.Name().Pkg } return pkg.Lookup(expr.Sel.Value) } @@ -948,7 +948,7 @@ func (p *noder) embedded(typ syntax.Expr) *ir.Node { n.SetEmbedded(true) if isStar { - n.Left = p.nod(op, ir.ODEREF, n.Left, nil) + n.SetLeft(p.nod(op, ir.ODEREF, n.Left(), nil)) } return n } @@ -962,8 +962,8 @@ func (p *noder) stmtsFall(stmts []syntax.Stmt, fallOK bool) []*ir.Node { for i, stmt := range stmts { s := p.stmtFall(stmt, fallOK && i+1 == len(stmts)) if s == nil { - } else if s.Op == ir.OBLOCK && s.Ninit.Len() == 0 { - nodes = append(nodes, s.List.Slice()...) + } else if s.Op() == ir.OBLOCK && s.Init().Len() == 0 { + nodes = append(nodes, s.List().Slice()...) } else { nodes = append(nodes, s) } @@ -1010,12 +1010,12 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *ir.Node { if len(lhs) == 1 && len(rhs) == 1 { // common case - n.Left = lhs[0] - n.Right = rhs[0] + n.SetLeft(lhs[0]) + n.SetRight(rhs[0]) } else { - n.Op = ir.OAS2 - n.List.Set(lhs) - n.Rlist.Set(rhs) + n.SetOp(ir.OAS2) + n.PtrList().Set(lhs) + n.PtrRlist().Set(rhs) } return n @@ -1038,7 +1038,7 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *ir.Node { } n := p.nod(stmt, op, nil, nil) if stmt.Label != nil { - n.Sym = p.name(stmt.Label) + n.SetSym(p.name(stmt.Label)) } return n case *syntax.CallStmt: @@ -1058,17 +1058,17 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *ir.Node { results = p.exprList(stmt.Results) } n := p.nod(stmt, ir.ORETURN, nil, nil) - n.List.Set(results) - if n.List.Len() == 0 && Curfn != nil { - for _, ln := range Curfn.Func.Dcl { + n.PtrList().Set(results) + if n.List().Len() == 0 && Curfn != nil { + for _, ln := range Curfn.Func().Dcl { if ln.Class() == ir.PPARAM { continue } if ln.Class() != ir.PPARAMOUT { break } - if ir.AsNode(ln.Sym.Def) != ln { - base.Errorf("%s is shadowed during return", ln.Sym.Name) + if ir.AsNode(ln.Sym().Def) != ln { + base.Errorf("%s is shadowed during return", ln.Sym().Name) } } } @@ -1134,13 +1134,13 @@ func (p *noder) assignList(expr syntax.Expr, defn *ir.Node, colas bool) []*ir.No newOrErr = true n := NewName(sym) declare(n, dclcontext) - n.Name.Defn = defn - defn.Ninit.Append(ir.Nod(ir.ODCL, n, nil)) + n.Name().Defn = defn + defn.PtrInit().Append(ir.Nod(ir.ODCL, n, nil)) res[i] = n } if !newOrErr { - base.ErrorfAt(defn.Pos, "no new variables on left side of :=") + base.ErrorfAt(defn.Pos(), "no new variables on left side of :=") } return res } @@ -1156,18 +1156,18 @@ func (p *noder) ifStmt(stmt *syntax.IfStmt) *ir.Node { p.openScope(stmt.Pos()) n := p.nod(stmt, ir.OIF, nil, nil) if stmt.Init != nil { - n.Ninit.Set1(p.stmt(stmt.Init)) + n.PtrInit().Set1(p.stmt(stmt.Init)) } if stmt.Cond != nil { - n.Left = p.expr(stmt.Cond) + n.SetLeft(p.expr(stmt.Cond)) } - n.Nbody.Set(p.blockStmt(stmt.Then)) + n.PtrBody().Set(p.blockStmt(stmt.Then)) if stmt.Else != nil { e := p.stmt(stmt.Else) - if e.Op == ir.OBLOCK && e.Ninit.Len() == 0 { - n.Rlist.Set(e.List.Slice()) + if e.Op() == ir.OBLOCK && e.Init().Len() == 0 { + n.PtrRlist().Set(e.List().Slice()) } else { - n.Rlist.Set1(e) + n.PtrRlist().Set1(e) } } p.closeAnotherScope() @@ -1184,21 +1184,21 @@ func (p *noder) forStmt(stmt *syntax.ForStmt) *ir.Node { n = p.nod(r, ir.ORANGE, nil, p.expr(r.X)) if r.Lhs != nil { - n.List.Set(p.assignList(r.Lhs, n, r.Def)) + n.PtrList().Set(p.assignList(r.Lhs, n, r.Def)) } } else { n = p.nod(stmt, ir.OFOR, nil, nil) if stmt.Init != nil { - n.Ninit.Set1(p.stmt(stmt.Init)) + n.PtrInit().Set1(p.stmt(stmt.Init)) } if stmt.Cond != nil { - n.Left = p.expr(stmt.Cond) + n.SetLeft(p.expr(stmt.Cond)) } if stmt.Post != nil { - n.Right = p.stmt(stmt.Post) + n.SetRight(p.stmt(stmt.Post)) } } - n.Nbody.Set(p.blockStmt(stmt.Body)) + n.PtrBody().Set(p.blockStmt(stmt.Body)) p.closeAnotherScope() return n } @@ -1207,17 +1207,17 @@ func (p *noder) switchStmt(stmt *syntax.SwitchStmt) *ir.Node { p.openScope(stmt.Pos()) n := p.nod(stmt, ir.OSWITCH, nil, nil) if stmt.Init != nil { - n.Ninit.Set1(p.stmt(stmt.Init)) + n.PtrInit().Set1(p.stmt(stmt.Init)) } if stmt.Tag != nil { - n.Left = p.expr(stmt.Tag) + n.SetLeft(p.expr(stmt.Tag)) } - tswitch := n.Left - if tswitch != nil && tswitch.Op != ir.OTYPESW { + tswitch := n.Left() + if tswitch != nil && tswitch.Op() != ir.OTYPESW { tswitch = nil } - n.List.Set(p.caseClauses(stmt.Body, tswitch, stmt.Rbrace)) + n.PtrList().Set(p.caseClauses(stmt.Body, tswitch, stmt.Rbrace)) p.closeScope(stmt.Rbrace) return n @@ -1234,14 +1234,14 @@ func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *ir.Node, rbra n := p.nod(clause, ir.OCASE, nil, nil) if clause.Cases != nil { - n.List.Set(p.exprList(clause.Cases)) + n.PtrList().Set(p.exprList(clause.Cases)) } - if tswitch != nil && tswitch.Left != nil { - nn := NewName(tswitch.Left.Sym) + if tswitch != nil && tswitch.Left() != nil { + nn := NewName(tswitch.Left().Sym()) declare(nn, dclcontext) - n.Rlist.Set1(nn) + n.PtrRlist().Set1(nn) // keep track of the instances for reporting unused - nn.Name.Defn = tswitch + nn.Name().Defn = tswitch } // Trim trailing empty statements. We omit them from @@ -1255,8 +1255,8 @@ func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *ir.Node, rbra body = body[:len(body)-1] } - n.Nbody.Set(p.stmtsFall(body, true)) - if l := n.Nbody.Len(); l > 0 && n.Nbody.Index(l-1).Op == ir.OFALL { + n.PtrBody().Set(p.stmtsFall(body, true)) + if l := n.Body().Len(); l > 0 && n.Body().Index(l-1).Op() == ir.OFALL { if tswitch != nil { base.Errorf("cannot fallthrough in type switch") } @@ -1275,7 +1275,7 @@ func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *ir.Node, rbra func (p *noder) selectStmt(stmt *syntax.SelectStmt) *ir.Node { n := p.nod(stmt, ir.OSELECT, nil, nil) - n.List.Set(p.commClauses(stmt.Body, stmt.Rbrace)) + n.PtrList().Set(p.commClauses(stmt.Body, stmt.Rbrace)) return n } @@ -1290,9 +1290,9 @@ func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []* n := p.nod(clause, ir.OCASE, nil, nil) if clause.Comm != nil { - n.List.Set1(p.stmt(clause.Comm)) + n.PtrList().Set1(p.stmt(clause.Comm)) } - n.Nbody.Set(p.stmts(clause.Body)) + n.PtrBody().Set(p.stmts(clause.Body)) nodes = append(nodes, n) } if len(clauses) > 0 { @@ -1309,11 +1309,11 @@ func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) *ir.Node { ls = p.stmtFall(label.Stmt, fallOK) } - lhs.Name.Defn = ls + lhs.Name().Defn = ls l := []*ir.Node{lhs} if ls != nil { - if ls.Op == ir.OBLOCK && ls.Ninit.Len() == 0 { - l = append(l, ls.List.Slice()...) + if ls.Op() == ir.OBLOCK && ls.Init().Len() == 0 { + l = append(l, ls.List().Slice()...) } else { l = append(l, ls) } @@ -1451,9 +1451,9 @@ func (p *noder) mkname(name *syntax.Name) *ir.Node { func (p *noder) wrapname(n syntax.Node, x *ir.Node) *ir.Node { // These nodes do not carry line numbers. // Introduce a wrapper node to give them the correct line. - switch x.Op { + switch x.Op() { case ir.OTYPE, ir.OLITERAL: - if x.Sym == nil { + if x.Sym() == nil { break } fallthrough @@ -1470,7 +1470,7 @@ func (p *noder) nod(orig syntax.Node, op ir.Op, left, right *ir.Node) *ir.Node { func (p *noder) nodSym(orig syntax.Node, op ir.Op, left *ir.Node, sym *types.Sym) *ir.Node { n := nodSym(op, left, sym) - n.Pos = p.pos(orig) + n.SetPos(p.pos(orig)) return n } @@ -1670,8 +1670,8 @@ func safeArg(name string) bool { func mkname(sym *types.Sym) *ir.Node { n := oldname(sym) - if n.Name != nil && n.Name.Pack != nil { - n.Name.Pack.Name.SetUsed(true) + if n.Name() != nil && n.Name().Pack != nil { + n.Name().Pack.Name().SetUsed(true) } return n } diff --git a/src/cmd/compile/internal/gc/obj.go b/src/cmd/compile/internal/gc/obj.go index 2961dbf636..9f0cefbd1c 100644 --- a/src/cmd/compile/internal/gc/obj.go +++ b/src/cmd/compile/internal/gc/obj.go @@ -142,7 +142,7 @@ func dumpdata() { for { for i := xtops; i < len(xtop); i++ { n := xtop[i] - if n.Op == ir.ODCLFUNC { + if n.Op() == ir.ODCLFUNC { funccompile(n) } } @@ -204,12 +204,12 @@ func addptabs() { return } for _, exportn := range exportlist { - s := exportn.Sym + s := exportn.Sym() n := ir.AsNode(s.Def) if n == nil { continue } - if n.Op != ir.ONAME { + if n.Op() != ir.ONAME { continue } if !types.IsExported(s.Name) { @@ -218,37 +218,37 @@ func addptabs() { if s.Pkg.Name != "main" { continue } - if n.Type.Etype == types.TFUNC && n.Class() == ir.PFUNC { + if n.Type().Etype == types.TFUNC && n.Class() == ir.PFUNC { // function - ptabs = append(ptabs, ptabEntry{s: s, t: ir.AsNode(s.Def).Type}) + ptabs = append(ptabs, ptabEntry{s: s, t: ir.AsNode(s.Def).Type()}) } else { // variable - ptabs = append(ptabs, ptabEntry{s: s, t: types.NewPtr(ir.AsNode(s.Def).Type)}) + ptabs = append(ptabs, ptabEntry{s: s, t: types.NewPtr(ir.AsNode(s.Def).Type())}) } } } func dumpGlobal(n *ir.Node) { - if n.Type == nil { + if n.Type() == nil { base.Fatalf("external %v nil type\n", n) } if n.Class() == ir.PFUNC { return } - if n.Sym.Pkg != ir.LocalPkg { + if n.Sym().Pkg != ir.LocalPkg { return } - dowidth(n.Type) + dowidth(n.Type()) ggloblnod(n) } func dumpGlobalConst(n *ir.Node) { // only export typed constants - t := n.Type + t := n.Type() if t == nil { return } - if n.Sym.Pkg != ir.LocalPkg { + if n.Sym().Pkg != ir.LocalPkg { return } // only export integer constants for now @@ -263,13 +263,13 @@ func dumpGlobalConst(n *ir.Node) { return } } - base.Ctxt.DwarfIntConst(base.Ctxt.Pkgpath, n.Sym.Name, typesymname(t), ir.Int64Val(t, v)) + base.Ctxt.DwarfIntConst(base.Ctxt.Pkgpath, n.Sym().Name, typesymname(t), ir.Int64Val(t, v)) } func dumpglobls() { // add globals for _, n := range externdcl { - switch n.Op { + switch n.Op() { case ir.ONAME: dumpGlobal(n) case ir.OLITERAL: @@ -414,7 +414,7 @@ func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj. if readonly { sym = stringsym(pos, string(data)) } else { - sym = slicedata(pos, string(data)).Sym.Linksym() + sym = slicedata(pos, string(data)).Sym().Linksym() } if len(hash) > 0 { sum := sha256.Sum256(data) @@ -462,7 +462,7 @@ func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj. } else { // Emit a zero-length data symbol // and then fix up length and content to use file. - symdata = slicedata(pos, "").Sym.Linksym() + symdata = slicedata(pos, "").Sym().Linksym() symdata.Size = size symdata.Type = objabi.SNOPTRDATA info := symdata.NewFileInfo() @@ -490,10 +490,10 @@ func slicedata(pos src.XPos, s string) *ir.Node { } func slicebytes(nam *ir.Node, s string) { - if nam.Op != ir.ONAME { + if nam.Op() != ir.ONAME { base.Fatalf("slicebytes %v", nam) } - slicesym(nam, slicedata(nam.Pos, s), int64(len(s))) + slicesym(nam, slicedata(nam.Pos(), s), int64(len(s))) } func dstringdata(s *obj.LSym, off int, t string, pos src.XPos, what string) int { @@ -531,12 +531,12 @@ func dsymptrWeakOff(s *obj.LSym, off int, x *obj.LSym) int { // slicesym writes a static slice symbol {&arr, lencap, lencap} to n. // arr must be an ONAME. slicesym does not modify n. func slicesym(n, arr *ir.Node, lencap int64) { - s := n.Sym.Linksym() - off := n.Xoffset - if arr.Op != ir.ONAME { + s := n.Sym().Linksym() + off := n.Offset() + if arr.Op() != ir.ONAME { base.Fatalf("slicesym non-name arr %v", arr) } - s.WriteAddr(base.Ctxt, off, Widthptr, arr.Sym.Linksym(), arr.Xoffset) + s.WriteAddr(base.Ctxt, off, Widthptr, arr.Sym().Linksym(), arr.Offset()) s.WriteInt(base.Ctxt, off+sliceLenOffset, Widthptr, lencap) s.WriteInt(base.Ctxt, off+sliceCapOffset, Widthptr, lencap) } @@ -544,88 +544,88 @@ func slicesym(n, arr *ir.Node, lencap int64) { // addrsym writes the static address of a to n. a must be an ONAME. // Neither n nor a is modified. func addrsym(n, a *ir.Node) { - if n.Op != ir.ONAME { - base.Fatalf("addrsym n op %v", n.Op) + if n.Op() != ir.ONAME { + base.Fatalf("addrsym n op %v", n.Op()) } - if n.Sym == nil { + if n.Sym() == nil { base.Fatalf("addrsym nil n sym") } - if a.Op != ir.ONAME { - base.Fatalf("addrsym a op %v", a.Op) + if a.Op() != ir.ONAME { + base.Fatalf("addrsym a op %v", a.Op()) } - s := n.Sym.Linksym() - s.WriteAddr(base.Ctxt, n.Xoffset, Widthptr, a.Sym.Linksym(), a.Xoffset) + s := n.Sym().Linksym() + s.WriteAddr(base.Ctxt, n.Offset(), Widthptr, a.Sym().Linksym(), a.Offset()) } // pfuncsym writes the static address of f to n. f must be a global function. // Neither n nor f is modified. func pfuncsym(n, f *ir.Node) { - if n.Op != ir.ONAME { - base.Fatalf("pfuncsym n op %v", n.Op) + if n.Op() != ir.ONAME { + base.Fatalf("pfuncsym n op %v", n.Op()) } - if n.Sym == nil { + if n.Sym() == nil { base.Fatalf("pfuncsym nil n sym") } if f.Class() != ir.PFUNC { base.Fatalf("pfuncsym class not PFUNC %d", f.Class()) } - s := n.Sym.Linksym() - s.WriteAddr(base.Ctxt, n.Xoffset, Widthptr, funcsym(f.Sym).Linksym(), f.Xoffset) + s := n.Sym().Linksym() + s.WriteAddr(base.Ctxt, n.Offset(), Widthptr, funcsym(f.Sym()).Linksym(), f.Offset()) } // litsym writes the static literal c to n. // Neither n nor c is modified. func litsym(n, c *ir.Node, wid int) { - if n.Op != ir.ONAME { - base.Fatalf("litsym n op %v", n.Op) + if n.Op() != ir.ONAME { + base.Fatalf("litsym n op %v", n.Op()) } - if n.Sym == nil { + if n.Sym() == nil { base.Fatalf("litsym nil n sym") } - if !types.Identical(n.Type, c.Type) { - base.Fatalf("litsym: type mismatch: %v has type %v, but %v has type %v", n, n.Type, c, c.Type) + if !types.Identical(n.Type(), c.Type()) { + base.Fatalf("litsym: type mismatch: %v has type %v, but %v has type %v", n, n.Type(), c, c.Type()) } - if c.Op == ir.ONIL { + if c.Op() == ir.ONIL { return } - if c.Op != ir.OLITERAL { - base.Fatalf("litsym c op %v", c.Op) + if c.Op() != ir.OLITERAL { + base.Fatalf("litsym c op %v", c.Op()) } - s := n.Sym.Linksym() + s := n.Sym().Linksym() switch u := c.Val(); u.Kind() { case constant.Bool: i := int64(obj.Bool2int(constant.BoolVal(u))) - s.WriteInt(base.Ctxt, n.Xoffset, wid, i) + s.WriteInt(base.Ctxt, n.Offset(), wid, i) case constant.Int: - s.WriteInt(base.Ctxt, n.Xoffset, wid, ir.Int64Val(n.Type, u)) + s.WriteInt(base.Ctxt, n.Offset(), wid, ir.Int64Val(n.Type(), u)) case constant.Float: f, _ := constant.Float64Val(u) - switch n.Type.Etype { + switch n.Type().Etype { case types.TFLOAT32: - s.WriteFloat32(base.Ctxt, n.Xoffset, float32(f)) + s.WriteFloat32(base.Ctxt, n.Offset(), float32(f)) case types.TFLOAT64: - s.WriteFloat64(base.Ctxt, n.Xoffset, f) + s.WriteFloat64(base.Ctxt, n.Offset(), f) } case constant.Complex: re, _ := constant.Float64Val(constant.Real(u)) im, _ := constant.Float64Val(constant.Imag(u)) - switch n.Type.Etype { + switch n.Type().Etype { case types.TCOMPLEX64: - s.WriteFloat32(base.Ctxt, n.Xoffset, float32(re)) - s.WriteFloat32(base.Ctxt, n.Xoffset+4, float32(im)) + s.WriteFloat32(base.Ctxt, n.Offset(), float32(re)) + s.WriteFloat32(base.Ctxt, n.Offset()+4, float32(im)) case types.TCOMPLEX128: - s.WriteFloat64(base.Ctxt, n.Xoffset, re) - s.WriteFloat64(base.Ctxt, n.Xoffset+8, im) + s.WriteFloat64(base.Ctxt, n.Offset(), re) + s.WriteFloat64(base.Ctxt, n.Offset()+8, im) } case constant.String: i := constant.StringVal(u) - symdata := stringsym(n.Pos, i) - s.WriteAddr(base.Ctxt, n.Xoffset, Widthptr, symdata, 0) - s.WriteInt(base.Ctxt, n.Xoffset+int64(Widthptr), Widthptr, int64(len(i))) + symdata := stringsym(n.Pos(), i) + s.WriteAddr(base.Ctxt, n.Offset(), Widthptr, symdata, 0) + s.WriteInt(base.Ctxt, n.Offset()+int64(Widthptr), Widthptr, int64(len(i))) default: base.Fatalf("litsym unhandled OLITERAL %v", c) diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go index 3bd49e8094..36a4095640 100644 --- a/src/cmd/compile/internal/gc/order.go +++ b/src/cmd/compile/internal/gc/order.go @@ -53,11 +53,11 @@ type Order struct { // described in the comment at the top of the file. func order(fn *ir.Node) { if base.Flag.W > 1 { - s := fmt.Sprintf("\nbefore order %v", fn.Func.Nname.Sym) - ir.DumpList(s, fn.Nbody) + s := fmt.Sprintf("\nbefore order %v", fn.Func().Nname.Sym()) + ir.DumpList(s, fn.Body()) } - orderBlock(&fn.Nbody, map[string][]*ir.Node{}) + orderBlock(fn.PtrBody(), map[string][]*ir.Node{}) } // newTemp allocates a new temporary with the given type, @@ -70,7 +70,7 @@ func (o *Order) newTemp(t *types.Type, clear bool) *ir.Node { key := t.LongString() a := o.free[key] for i, n := range a { - if types.Identical(t, n.Type) { + if types.Identical(t, n.Type()) { v = a[i] a[i] = a[len(a)-1] a = a[:len(a)-1] @@ -120,20 +120,20 @@ func (o *Order) cheapExpr(n *ir.Node) *ir.Node { return nil } - switch n.Op { + switch n.Op() { case ir.ONAME, ir.OLITERAL, ir.ONIL: return n case ir.OLEN, ir.OCAP: - l := o.cheapExpr(n.Left) - if l == n.Left { + l := o.cheapExpr(n.Left()) + if l == n.Left() { return n } a := ir.SepCopy(n) - a.Left = l + a.SetLeft(l) return typecheck(a, ctxExpr) } - return o.copyExpr(n, n.Type, false) + return o.copyExpr(n, n.Type(), false) } // safeExpr returns a safe version of n. @@ -144,46 +144,46 @@ func (o *Order) cheapExpr(n *ir.Node) *ir.Node { // // The intended use is to apply to x when rewriting x += y into x = x + y. func (o *Order) safeExpr(n *ir.Node) *ir.Node { - switch n.Op { + switch n.Op() { case ir.ONAME, ir.OLITERAL, ir.ONIL: return n case ir.ODOT, ir.OLEN, ir.OCAP: - l := o.safeExpr(n.Left) - if l == n.Left { + l := o.safeExpr(n.Left()) + if l == n.Left() { return n } a := ir.SepCopy(n) - a.Left = l + a.SetLeft(l) return typecheck(a, ctxExpr) case ir.ODOTPTR, ir.ODEREF: - l := o.cheapExpr(n.Left) - if l == n.Left { + l := o.cheapExpr(n.Left()) + if l == n.Left() { return n } a := ir.SepCopy(n) - a.Left = l + a.SetLeft(l) return typecheck(a, ctxExpr) case ir.OINDEX, ir.OINDEXMAP: var l *ir.Node - if n.Left.Type.IsArray() { - l = o.safeExpr(n.Left) + if n.Left().Type().IsArray() { + l = o.safeExpr(n.Left()) } else { - l = o.cheapExpr(n.Left) + l = o.cheapExpr(n.Left()) } - r := o.cheapExpr(n.Right) - if l == n.Left && r == n.Right { + r := o.cheapExpr(n.Right()) + if l == n.Left() && r == n.Right() { return n } a := ir.SepCopy(n) - a.Left = l - a.Right = r + a.SetLeft(l) + a.SetRight(r) return typecheck(a, ctxExpr) default: - base.Fatalf("order.safeExpr %v", n.Op) + base.Fatalf("order.safeExpr %v", n.Op()) return nil // not reached } } @@ -195,7 +195,7 @@ func (o *Order) safeExpr(n *ir.Node) *ir.Node { // because we emit explicit VARKILL instructions marking the end of those // temporaries' lifetimes. func isaddrokay(n *ir.Node) bool { - return islvalue(n) && (n.Op != ir.ONAME || n.Class() == ir.PEXTERN || ir.IsAutoTmp(n)) + return islvalue(n) && (n.Op() != ir.ONAME || n.Class() == ir.PEXTERN || ir.IsAutoTmp(n)) } // addrTemp ensures that n is okay to pass by address to runtime routines. @@ -204,11 +204,11 @@ func isaddrokay(n *ir.Node) bool { // The result of addrTemp MUST be assigned back to n, e.g. // n.Left = o.addrTemp(n.Left) func (o *Order) addrTemp(n *ir.Node) *ir.Node { - if n.Op == ir.OLITERAL || n.Op == ir.ONIL { + if n.Op() == ir.OLITERAL || n.Op() == ir.ONIL { // TODO: expand this to all static composite literal nodes? n = defaultlit(n, nil) - dowidth(n.Type) - vstat := readonlystaticname(n.Type) + dowidth(n.Type()) + vstat := readonlystaticname(n.Type()) var s InitSchedule s.staticassign(vstat, n) if s.out != nil { @@ -220,7 +220,7 @@ func (o *Order) addrTemp(n *ir.Node) *ir.Node { if isaddrokay(n) { return n } - return o.copyExpr(n, n.Type, false) + return o.copyExpr(n, n.Type(), false) } // mapKeyTemp prepares n to be a key in a map runtime call and returns n. @@ -250,20 +250,20 @@ func (o *Order) mapKeyTemp(t *types.Type, n *ir.Node) *ir.Node { // comes up in important cases in practice. See issue 3512. func mapKeyReplaceStrConv(n *ir.Node) bool { var replaced bool - switch n.Op { + switch n.Op() { case ir.OBYTES2STR: - n.Op = ir.OBYTES2STRTMP + n.SetOp(ir.OBYTES2STRTMP) replaced = true case ir.OSTRUCTLIT: - for _, elem := range n.List.Slice() { - if mapKeyReplaceStrConv(elem.Left) { + for _, elem := range n.List().Slice() { + if mapKeyReplaceStrConv(elem.Left()) { replaced = true } } case ir.OARRAYLIT: - for _, elem := range n.List.Slice() { - if elem.Op == ir.OKEY { - elem = elem.Right + for _, elem := range n.List().Slice() { + if elem.Op() == ir.OKEY { + elem = elem.Right() } if mapKeyReplaceStrConv(elem) { replaced = true @@ -284,7 +284,7 @@ func (o *Order) markTemp() ordermarker { // which must have been returned by markTemp. func (o *Order) popTemp(mark ordermarker) { for _, n := range o.temp[mark:] { - key := n.Type.LongString() + key := n.Type().LongString() o.free[key] = append(o.free[key], n) } o.temp = o.temp[:mark] @@ -336,46 +336,46 @@ func orderMakeSliceCopy(s []*ir.Node) { asn := s[0] copyn := s[1] - if asn == nil || asn.Op != ir.OAS { + if asn == nil || asn.Op() != ir.OAS { return } - if asn.Left.Op != ir.ONAME { + if asn.Left().Op() != ir.ONAME { return } - if ir.IsBlank(asn.Left) { + if ir.IsBlank(asn.Left()) { return } - maken := asn.Right - if maken == nil || maken.Op != ir.OMAKESLICE { + maken := asn.Right() + if maken == nil || maken.Op() != ir.OMAKESLICE { return } - if maken.Esc == EscNone { + if maken.Esc() == EscNone { return } - if maken.Left == nil || maken.Right != nil { + if maken.Left() == nil || maken.Right() != nil { return } - if copyn.Op != ir.OCOPY { + if copyn.Op() != ir.OCOPY { return } - if copyn.Left.Op != ir.ONAME { + if copyn.Left().Op() != ir.ONAME { return } - if asn.Left.Sym != copyn.Left.Sym { + if asn.Left().Sym() != copyn.Left().Sym() { return } - if copyn.Right.Op != ir.ONAME { + if copyn.Right().Op() != ir.ONAME { return } - if copyn.Left.Sym == copyn.Right.Sym { + if copyn.Left().Sym() == copyn.Right().Sym() { return } - maken.Op = ir.OMAKESLICECOPY - maken.Right = copyn.Right + maken.SetOp(ir.OMAKESLICECOPY) + maken.SetRight(copyn.Right()) // Set bounded when m = OMAKESLICE([]T, len(s)); OCOPY(m, s) - maken.SetBounded(maken.Left.Op == ir.OLEN && samesafeexpr(maken.Left.Left, copyn.Right)) + maken.SetBounded(maken.Left().Op() == ir.OLEN && samesafeexpr(maken.Left().Left(), copyn.Right())) maken = typecheck(maken, ctxExpr) @@ -393,7 +393,7 @@ func (o *Order) edge() { // Create a new uint8 counter to be allocated in section // __libfuzzer_extra_counters. counter := staticname(types.Types[types.TUINT8]) - counter.Name.SetLibfuzzerExtraCounter(true) + counter.Name().SetLibfuzzerExtraCounter(true) // counter += 1 incr := ir.Nod(ir.OASOP, counter, nodintconst(1)) @@ -451,36 +451,36 @@ func (o *Order) init(n *ir.Node) { if ir.MayBeShared(n) { // For concurrency safety, don't mutate potentially shared nodes. // First, ensure that no work is required here. - if n.Ninit.Len() > 0 { + if n.Init().Len() > 0 { base.Fatalf("order.init shared node with ninit") } return } - o.stmtList(n.Ninit) - n.Ninit.Set(nil) + o.stmtList(n.Init()) + n.PtrInit().Set(nil) } // call orders the call expression n. // n.Op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY. func (o *Order) call(n *ir.Node) { - if n.Ninit.Len() > 0 { + if n.Init().Len() > 0 { // Caller should have already called o.init(n). - base.Fatalf("%v with unexpected ninit", n.Op) + base.Fatalf("%v with unexpected ninit", n.Op()) } // Builtin functions. - if n.Op != ir.OCALLFUNC && n.Op != ir.OCALLMETH && n.Op != ir.OCALLINTER { - n.Left = o.expr(n.Left, nil) - n.Right = o.expr(n.Right, nil) - o.exprList(n.List) + if n.Op() != ir.OCALLFUNC && n.Op() != ir.OCALLMETH && n.Op() != ir.OCALLINTER { + n.SetLeft(o.expr(n.Left(), nil)) + n.SetRight(o.expr(n.Right(), nil)) + o.exprList(n.List()) return } fixVariadicCall(n) - n.Left = o.expr(n.Left, nil) - o.exprList(n.List) + n.SetLeft(o.expr(n.Left(), nil)) + o.exprList(n.List()) - if n.Op == ir.OCALLINTER { + if n.Op() == ir.OCALLINTER { return } keepAlive := func(arg *ir.Node) { @@ -488,19 +488,19 @@ func (o *Order) call(n *ir.Node) { // arrange for the pointer to be kept alive until the call returns, // by copying it into a temp and marking that temp // still alive when we pop the temp stack. - if arg.Op == ir.OCONVNOP && arg.Left.Type.IsUnsafePtr() { - x := o.copyExpr(arg.Left, arg.Left.Type, false) - arg.Left = x - x.Name.SetAddrtaken(true) // ensure SSA keeps the x variable - n.Nbody.Append(typecheck(ir.Nod(ir.OVARLIVE, x, nil), ctxStmt)) + if arg.Op() == ir.OCONVNOP && arg.Left().Type().IsUnsafePtr() { + x := o.copyExpr(arg.Left(), arg.Left().Type(), false) + arg.SetLeft(x) + x.Name().SetAddrtaken(true) // ensure SSA keeps the x variable + n.PtrBody().Append(typecheck(ir.Nod(ir.OVARLIVE, x, nil), ctxStmt)) } } // Check for "unsafe-uintptr" tag provided by escape analysis. - for i, param := range n.Left.Type.Params().FieldSlice() { + for i, param := range n.Left().Type().Params().FieldSlice() { if param.Note == unsafeUintptrTag || param.Note == uintptrEscapesTag { - if arg := n.List.Index(i); arg.Op == ir.OSLICELIT { - for _, elt := range arg.List.Slice() { + if arg := n.List().Index(i); arg.Op() == ir.OSLICELIT { + for _, elt := range arg.List().Slice() { keepAlive(elt) } } else { @@ -526,40 +526,40 @@ func (o *Order) call(n *ir.Node) { // And this only applies to the multiple-assignment form. // We could do a more precise analysis if needed, like in walk.go. func (o *Order) mapAssign(n *ir.Node) { - switch n.Op { + switch n.Op() { default: - base.Fatalf("order.mapAssign %v", n.Op) + base.Fatalf("order.mapAssign %v", n.Op()) case ir.OAS, ir.OASOP: - if n.Left.Op == ir.OINDEXMAP { + if n.Left().Op() == ir.OINDEXMAP { // Make sure we evaluate the RHS before starting the map insert. // We need to make sure the RHS won't panic. See issue 22881. - if n.Right.Op == ir.OAPPEND { - s := n.Right.List.Slice()[1:] + if n.Right().Op() == ir.OAPPEND { + s := n.Right().List().Slice()[1:] for i, n := range s { s[i] = o.cheapExpr(n) } } else { - n.Right = o.cheapExpr(n.Right) + n.SetRight(o.cheapExpr(n.Right())) } } o.out = append(o.out, n) case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2MAPR, ir.OAS2FUNC: var post []*ir.Node - for i, m := range n.List.Slice() { + for i, m := range n.List().Slice() { switch { - case m.Op == ir.OINDEXMAP: - if !ir.IsAutoTmp(m.Left) { - m.Left = o.copyExpr(m.Left, m.Left.Type, false) + case m.Op() == ir.OINDEXMAP: + if !ir.IsAutoTmp(m.Left()) { + m.SetLeft(o.copyExpr(m.Left(), m.Left().Type(), false)) } - if !ir.IsAutoTmp(m.Right) { - m.Right = o.copyExpr(m.Right, m.Right.Type, false) + if !ir.IsAutoTmp(m.Right()) { + m.SetRight(o.copyExpr(m.Right(), m.Right().Type(), false)) } fallthrough - case instrumenting && n.Op == ir.OAS2FUNC && !ir.IsBlank(m): - t := o.newTemp(m.Type, false) - n.List.SetIndex(i, t) + case instrumenting && n.Op() == ir.OAS2FUNC && !ir.IsBlank(m): + t := o.newTemp(m.Type(), false) + n.List().SetIndex(i, t) a := ir.Nod(ir.OAS, m, t) a = typecheck(a, ctxStmt) post = append(post, a) @@ -582,43 +582,43 @@ func (o *Order) stmt(n *ir.Node) { lno := setlineno(n) o.init(n) - switch n.Op { + switch n.Op() { default: - base.Fatalf("order.stmt %v", n.Op) + base.Fatalf("order.stmt %v", n.Op()) case ir.OVARKILL, ir.OVARLIVE, ir.OINLMARK: o.out = append(o.out, n) case ir.OAS: t := o.markTemp() - n.Left = o.expr(n.Left, nil) - n.Right = o.expr(n.Right, n.Left) + n.SetLeft(o.expr(n.Left(), nil)) + n.SetRight(o.expr(n.Right(), n.Left())) o.mapAssign(n) o.cleanTemp(t) case ir.OASOP: t := o.markTemp() - n.Left = o.expr(n.Left, nil) - n.Right = o.expr(n.Right, nil) + n.SetLeft(o.expr(n.Left(), nil)) + n.SetRight(o.expr(n.Right(), nil)) - if instrumenting || n.Left.Op == ir.OINDEXMAP && (n.SubOp() == ir.ODIV || n.SubOp() == ir.OMOD) { + if instrumenting || n.Left().Op() == ir.OINDEXMAP && (n.SubOp() == ir.ODIV || n.SubOp() == ir.OMOD) { // Rewrite m[k] op= r into m[k] = m[k] op r so // that we can ensure that if op panics // because r is zero, the panic happens before // the map assignment. - n.Left = o.safeExpr(n.Left) + n.SetLeft(o.safeExpr(n.Left())) - l := treecopy(n.Left, src.NoXPos) - if l.Op == ir.OINDEXMAP { + l := treecopy(n.Left(), src.NoXPos) + if l.Op() == ir.OINDEXMAP { l.SetIndexMapLValue(false) } - l = o.copyExpr(l, n.Left.Type, false) - n.Right = ir.Nod(n.SubOp(), l, n.Right) - n.Right = typecheck(n.Right, ctxExpr) - n.Right = o.expr(n.Right, nil) + l = o.copyExpr(l, n.Left().Type(), false) + n.SetRight(ir.Nod(n.SubOp(), l, n.Right())) + n.SetRight(typecheck(n.Right(), ctxExpr)) + n.SetRight(o.expr(n.Right(), nil)) - n.Op = ir.OAS + n.SetOp(ir.OAS) n.ResetAux() } @@ -627,17 +627,17 @@ func (o *Order) stmt(n *ir.Node) { case ir.OAS2: t := o.markTemp() - o.exprList(n.List) - o.exprList(n.Rlist) + o.exprList(n.List()) + o.exprList(n.Rlist()) o.mapAssign(n) o.cleanTemp(t) // Special: avoid copy of func call n.Right case ir.OAS2FUNC: t := o.markTemp() - o.exprList(n.List) - o.init(n.Right) - o.call(n.Right) + o.exprList(n.List()) + o.init(n.Right()) + o.call(n.Right()) o.as2(n) o.cleanTemp(t) @@ -649,19 +649,19 @@ func (o *Order) stmt(n *ir.Node) { // and make sure OINDEXMAP is not copied out. case ir.OAS2DOTTYPE, ir.OAS2RECV, ir.OAS2MAPR: t := o.markTemp() - o.exprList(n.List) + o.exprList(n.List()) - switch r := n.Right; r.Op { + switch r := n.Right(); r.Op() { case ir.ODOTTYPE2, ir.ORECV: - r.Left = o.expr(r.Left, nil) + r.SetLeft(o.expr(r.Left(), nil)) case ir.OINDEXMAP: - r.Left = o.expr(r.Left, nil) - r.Right = o.expr(r.Right, nil) + r.SetLeft(o.expr(r.Left(), nil)) + r.SetRight(o.expr(r.Right(), nil)) // See similar conversion for OINDEXMAP below. - _ = mapKeyReplaceStrConv(r.Right) - r.Right = o.mapKeyTemp(r.Left.Type, r.Right) + _ = mapKeyReplaceStrConv(r.Right()) + r.SetRight(o.mapKeyTemp(r.Left().Type(), r.Right())) default: - base.Fatalf("order.stmt: %v", r.Op) + base.Fatalf("order.stmt: %v", r.Op()) } o.okAs2(n) @@ -669,7 +669,7 @@ func (o *Order) stmt(n *ir.Node) { // Special: does not save n onto out. case ir.OBLOCK, ir.OEMPTY: - o.stmtList(n.List) + o.stmtList(n.List()) // Special: n->left is not an expression; save as is. case ir.OBREAK, @@ -697,26 +697,26 @@ func (o *Order) stmt(n *ir.Node) { ir.ORECOVER, ir.ORECV: t := o.markTemp() - n.Left = o.expr(n.Left, nil) - n.Right = o.expr(n.Right, nil) - o.exprList(n.List) - o.exprList(n.Rlist) + n.SetLeft(o.expr(n.Left(), nil)) + n.SetRight(o.expr(n.Right(), nil)) + o.exprList(n.List()) + o.exprList(n.Rlist()) o.out = append(o.out, n) o.cleanTemp(t) // Special: order arguments to inner call but not call itself. case ir.ODEFER, ir.OGO: t := o.markTemp() - o.init(n.Left) - o.call(n.Left) + o.init(n.Left()) + o.call(n.Left()) o.out = append(o.out, n) o.cleanTemp(t) case ir.ODELETE: t := o.markTemp() - n.List.SetFirst(o.expr(n.List.First(), nil)) - n.List.SetSecond(o.expr(n.List.Second(), nil)) - n.List.SetSecond(o.mapKeyTemp(n.List.First().Type, n.List.Second())) + n.List().SetFirst(o.expr(n.List().First(), nil)) + n.List().SetSecond(o.expr(n.List().Second(), nil)) + n.List().SetSecond(o.mapKeyTemp(n.List().First().Type(), n.List().Second())) o.out = append(o.out, n) o.cleanTemp(t) @@ -724,10 +724,10 @@ func (o *Order) stmt(n *ir.Node) { // beginning of loop body and after for statement. case ir.OFOR: t := o.markTemp() - n.Left = o.exprInPlace(n.Left) - n.Nbody.Prepend(o.cleanTempNoPop(t)...) - orderBlock(&n.Nbody, o.free) - n.Right = orderStmtInPlace(n.Right, o.free) + n.SetLeft(o.exprInPlace(n.Left())) + n.PtrBody().Prepend(o.cleanTempNoPop(t)...) + orderBlock(n.PtrBody(), o.free) + n.SetRight(orderStmtInPlace(n.Right(), o.free)) o.out = append(o.out, n) o.cleanTemp(t) @@ -735,21 +735,21 @@ func (o *Order) stmt(n *ir.Node) { // beginning of both branches. case ir.OIF: t := o.markTemp() - n.Left = o.exprInPlace(n.Left) - n.Nbody.Prepend(o.cleanTempNoPop(t)...) - n.Rlist.Prepend(o.cleanTempNoPop(t)...) + n.SetLeft(o.exprInPlace(n.Left())) + n.PtrBody().Prepend(o.cleanTempNoPop(t)...) + n.PtrRlist().Prepend(o.cleanTempNoPop(t)...) o.popTemp(t) - orderBlock(&n.Nbody, o.free) - orderBlock(&n.Rlist, o.free) + orderBlock(n.PtrBody(), o.free) + orderBlock(n.PtrRlist(), o.free) o.out = append(o.out, n) // Special: argument will be converted to interface using convT2E // so make sure it is an addressable temporary. case ir.OPANIC: t := o.markTemp() - n.Left = o.expr(n.Left, nil) - if !n.Left.Type.IsInterface() { - n.Left = o.addrTemp(n.Left) + n.SetLeft(o.expr(n.Left(), nil)) + if !n.Left().Type().IsInterface() { + n.SetLeft(o.addrTemp(n.Left())) } o.out = append(o.out, n) o.cleanTemp(t) @@ -768,20 +768,20 @@ func (o *Order) stmt(n *ir.Node) { // Mark []byte(str) range expression to reuse string backing storage. // It is safe because the storage cannot be mutated. - if n.Right.Op == ir.OSTR2BYTES { - n.Right.Op = ir.OSTR2BYTESTMP + if n.Right().Op() == ir.OSTR2BYTES { + n.Right().SetOp(ir.OSTR2BYTESTMP) } t := o.markTemp() - n.Right = o.expr(n.Right, nil) + n.SetRight(o.expr(n.Right(), nil)) orderBody := true - switch n.Type.Etype { + switch n.Type().Etype { default: - base.Fatalf("order.stmt range %v", n.Type) + base.Fatalf("order.stmt range %v", n.Type()) case types.TARRAY, types.TSLICE: - if n.List.Len() < 2 || ir.IsBlank(n.List.Second()) { + if n.List().Len() < 2 || ir.IsBlank(n.List().Second()) { // for i := range x will only use x once, to compute len(x). // No need to copy it. break @@ -791,15 +791,15 @@ func (o *Order) stmt(n *ir.Node) { case types.TCHAN, types.TSTRING: // chan, string, slice, array ranges use value multiple times. // make copy. - r := n.Right + r := n.Right() - if r.Type.IsString() && r.Type != types.Types[types.TSTRING] { + if r.Type().IsString() && r.Type() != types.Types[types.TSTRING] { r = ir.Nod(ir.OCONV, r, nil) - r.Type = types.Types[types.TSTRING] + r.SetType(types.Types[types.TSTRING]) r = typecheck(r, ctxExpr) } - n.Right = o.copyExpr(r, r.Type, false) + n.SetRight(o.copyExpr(r, r.Type(), false)) case types.TMAP: if isMapClear(n) { @@ -813,22 +813,22 @@ func (o *Order) stmt(n *ir.Node) { // copy the map value in case it is a map literal. // TODO(rsc): Make tmp = literal expressions reuse tmp. // For maps tmp is just one word so it hardly matters. - r := n.Right - n.Right = o.copyExpr(r, r.Type, false) + r := n.Right() + n.SetRight(o.copyExpr(r, r.Type(), false)) // prealloc[n] is the temp for the iterator. // hiter contains pointers and needs to be zeroed. - prealloc[n] = o.newTemp(hiter(n.Type), true) + prealloc[n] = o.newTemp(hiter(n.Type()), true) } - o.exprListInPlace(n.List) + o.exprListInPlace(n.List()) if orderBody { - orderBlock(&n.Nbody, o.free) + orderBlock(n.PtrBody(), o.free) } o.out = append(o.out, n) o.cleanTemp(t) case ir.ORETURN: - o.exprList(n.List) + o.exprList(n.List()) o.out = append(o.out, n) // Special: clean case temporaries in each block entry. @@ -843,25 +843,25 @@ func (o *Order) stmt(n *ir.Node) { case ir.OSELECT: t := o.markTemp() - for _, n2 := range n.List.Slice() { - if n2.Op != ir.OCASE { - base.Fatalf("order select case %v", n2.Op) + for _, n2 := range n.List().Slice() { + if n2.Op() != ir.OCASE { + base.Fatalf("order select case %v", n2.Op()) } - r := n2.Left + r := n2.Left() setlineno(n2) // Append any new body prologue to ninit. // The next loop will insert ninit into nbody. - if n2.Ninit.Len() != 0 { + if n2.Init().Len() != 0 { base.Fatalf("order select ninit") } if r == nil { continue } - switch r.Op { + switch r.Op() { default: ir.Dump("select case", r) - base.Fatalf("unknown op in select %v", r.Op) + base.Fatalf("unknown op in select %v", r.Op()) // If this is case x := <-ch or case x, y := <-ch, the case has // the ODCL nodes to declare x and y. We want to delay that @@ -870,19 +870,19 @@ func (o *Order) stmt(n *ir.Node) { case ir.OSELRECV, ir.OSELRECV2: if r.Colas() { i := 0 - if r.Ninit.Len() != 0 && r.Ninit.First().Op == ir.ODCL && r.Ninit.First().Left == r.Left { + if r.Init().Len() != 0 && r.Init().First().Op() == ir.ODCL && r.Init().First().Left() == r.Left() { i++ } - if i < r.Ninit.Len() && r.Ninit.Index(i).Op == ir.ODCL && r.List.Len() != 0 && r.Ninit.Index(i).Left == r.List.First() { + if i < r.Init().Len() && r.Init().Index(i).Op() == ir.ODCL && r.List().Len() != 0 && r.Init().Index(i).Left() == r.List().First() { i++ } - if i >= r.Ninit.Len() { - r.Ninit.Set(nil) + if i >= r.Init().Len() { + r.PtrInit().Set(nil) } } - if r.Ninit.Len() != 0 { - ir.DumpList("ninit", r.Ninit) + if r.Init().Len() != 0 { + ir.DumpList("ninit", r.Init()) base.Fatalf("ninit on select recv") } @@ -891,10 +891,10 @@ func (o *Order) stmt(n *ir.Node) { // r->left is x, r->ntest is ok, r->right is ORECV, r->right->left is c. // r->left == N means 'case <-c'. // c is always evaluated; x and ok are only evaluated when assigned. - r.Right.Left = o.expr(r.Right.Left, nil) + r.Right().SetLeft(o.expr(r.Right().Left(), nil)) - if r.Right.Left.Op != ir.ONAME { - r.Right.Left = o.copyExpr(r.Right.Left, r.Right.Left.Type, false) + if r.Right().Left().Op() != ir.ONAME { + r.Right().SetLeft(o.copyExpr(r.Right().Left(), r.Right().Left().Type(), false)) } // Introduce temporary for receive and move actual copy into case body. @@ -903,75 +903,75 @@ func (o *Order) stmt(n *ir.Node) { // temporary per distinct type, sharing the temp among all receives // with that temp. Similarly one ok bool could be shared among all // the x,ok receives. Not worth doing until there's a clear need. - if r.Left != nil && ir.IsBlank(r.Left) { - r.Left = nil + if r.Left() != nil && ir.IsBlank(r.Left()) { + r.SetLeft(nil) } - if r.Left != nil { + if r.Left() != nil { // use channel element type for temporary to avoid conversions, // such as in case interfacevalue = <-intchan. // the conversion happens in the OAS instead. - tmp1 := r.Left + tmp1 := r.Left() if r.Colas() { tmp2 := ir.Nod(ir.ODCL, tmp1, nil) tmp2 = typecheck(tmp2, ctxStmt) - n2.Ninit.Append(tmp2) + n2.PtrInit().Append(tmp2) } - r.Left = o.newTemp(r.Right.Left.Type.Elem(), r.Right.Left.Type.Elem().HasPointers()) - tmp2 := ir.Nod(ir.OAS, tmp1, r.Left) + r.SetLeft(o.newTemp(r.Right().Left().Type().Elem(), r.Right().Left().Type().Elem().HasPointers())) + tmp2 := ir.Nod(ir.OAS, tmp1, r.Left()) tmp2 = typecheck(tmp2, ctxStmt) - n2.Ninit.Append(tmp2) + n2.PtrInit().Append(tmp2) } - if r.List.Len() != 0 && ir.IsBlank(r.List.First()) { - r.List.Set(nil) + if r.List().Len() != 0 && ir.IsBlank(r.List().First()) { + r.PtrList().Set(nil) } - if r.List.Len() != 0 { - tmp1 := r.List.First() + if r.List().Len() != 0 { + tmp1 := r.List().First() if r.Colas() { tmp2 := ir.Nod(ir.ODCL, tmp1, nil) tmp2 = typecheck(tmp2, ctxStmt) - n2.Ninit.Append(tmp2) + n2.PtrInit().Append(tmp2) } - r.List.Set1(o.newTemp(types.Types[types.TBOOL], false)) - tmp2 := okas(tmp1, r.List.First()) + r.PtrList().Set1(o.newTemp(types.Types[types.TBOOL], false)) + tmp2 := okas(tmp1, r.List().First()) tmp2 = typecheck(tmp2, ctxStmt) - n2.Ninit.Append(tmp2) + n2.PtrInit().Append(tmp2) } - orderBlock(&n2.Ninit, o.free) + orderBlock(n2.PtrInit(), o.free) case ir.OSEND: - if r.Ninit.Len() != 0 { - ir.DumpList("ninit", r.Ninit) + if r.Init().Len() != 0 { + ir.DumpList("ninit", r.Init()) base.Fatalf("ninit on select send") } // case c <- x // r->left is c, r->right is x, both are always evaluated. - r.Left = o.expr(r.Left, nil) + r.SetLeft(o.expr(r.Left(), nil)) - if !ir.IsAutoTmp(r.Left) { - r.Left = o.copyExpr(r.Left, r.Left.Type, false) + if !ir.IsAutoTmp(r.Left()) { + r.SetLeft(o.copyExpr(r.Left(), r.Left().Type(), false)) } - r.Right = o.expr(r.Right, nil) - if !ir.IsAutoTmp(r.Right) { - r.Right = o.copyExpr(r.Right, r.Right.Type, false) + r.SetRight(o.expr(r.Right(), nil)) + if !ir.IsAutoTmp(r.Right()) { + r.SetRight(o.copyExpr(r.Right(), r.Right().Type(), false)) } } } // Now that we have accumulated all the temporaries, clean them. // Also insert any ninit queued during the previous loop. // (The temporary cleaning must follow that ninit work.) - for _, n3 := range n.List.Slice() { - orderBlock(&n3.Nbody, o.free) - n3.Nbody.Prepend(o.cleanTempNoPop(t)...) + for _, n3 := range n.List().Slice() { + orderBlock(n3.PtrBody(), o.free) + n3.PtrBody().Prepend(o.cleanTempNoPop(t)...) // TODO(mdempsky): Is this actually necessary? // walkselect appears to walk Ninit. - n3.Nbody.Prepend(n3.Ninit.Slice()...) - n3.Ninit.Set(nil) + n3.PtrBody().Prepend(n3.Init().Slice()...) + n3.PtrInit().Set(nil) } o.out = append(o.out, n) @@ -980,14 +980,14 @@ func (o *Order) stmt(n *ir.Node) { // Special: value being sent is passed as a pointer; make it addressable. case ir.OSEND: t := o.markTemp() - n.Left = o.expr(n.Left, nil) - n.Right = o.expr(n.Right, nil) + n.SetLeft(o.expr(n.Left(), nil)) + n.SetRight(o.expr(n.Right(), nil)) if instrumenting { // Force copying to the stack so that (chan T)(nil) <- x // is still instrumented as a read of x. - n.Right = o.copyExpr(n.Right, n.Right.Type, false) + n.SetRight(o.copyExpr(n.Right(), n.Right().Type(), false)) } else { - n.Right = o.addrTemp(n.Right) + n.SetRight(o.addrTemp(n.Right())) } o.out = append(o.out, n) o.cleanTemp(t) @@ -1002,17 +1002,17 @@ func (o *Order) stmt(n *ir.Node) { case ir.OSWITCH: if base.Debug.Libfuzzer != 0 && !hasDefaultCase(n) { // Add empty "default:" case for instrumentation. - n.List.Append(ir.Nod(ir.OCASE, nil, nil)) + n.PtrList().Append(ir.Nod(ir.OCASE, nil, nil)) } t := o.markTemp() - n.Left = o.expr(n.Left, nil) - for _, ncas := range n.List.Slice() { - if ncas.Op != ir.OCASE { - base.Fatalf("order switch case %v", ncas.Op) + n.SetLeft(o.expr(n.Left(), nil)) + for _, ncas := range n.List().Slice() { + if ncas.Op() != ir.OCASE { + base.Fatalf("order switch case %v", ncas.Op()) } - o.exprListInPlace(ncas.List) - orderBlock(&ncas.Nbody, o.free) + o.exprListInPlace(ncas.List()) + orderBlock(ncas.PtrBody(), o.free) } o.out = append(o.out, n) @@ -1023,11 +1023,11 @@ func (o *Order) stmt(n *ir.Node) { } func hasDefaultCase(n *ir.Node) bool { - for _, ncas := range n.List.Slice() { - if ncas.Op != ir.OCASE { - base.Fatalf("expected case, found %v", ncas.Op) + for _, ncas := range n.List().Slice() { + if ncas.Op() != ir.OCASE { + base.Fatalf("expected case, found %v", ncas.Op()) } - if ncas.List.Len() == 0 { + if ncas.List().Len() == 0 { return true } } @@ -1069,21 +1069,21 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { lno := setlineno(n) o.init(n) - switch n.Op { + switch n.Op() { default: - n.Left = o.expr(n.Left, nil) - n.Right = o.expr(n.Right, nil) - o.exprList(n.List) - o.exprList(n.Rlist) + n.SetLeft(o.expr(n.Left(), nil)) + n.SetRight(o.expr(n.Right(), nil)) + o.exprList(n.List()) + o.exprList(n.Rlist()) // Addition of strings turns into a function call. // Allocate a temporary to hold the strings. // Fewer than 5 strings use direct runtime helpers. case ir.OADDSTR: - o.exprList(n.List) + o.exprList(n.List()) - if n.List.Len() > 5 { - t := types.NewArray(types.Types[types.TSTRING], int64(n.List.Len())) + if n.List().Len() > 5 { + t := types.NewArray(types.Types[types.TSTRING], int64(n.List().Len())) prealloc[n] = o.newTemp(t, false) } @@ -1097,22 +1097,22 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { hasbyte := false haslit := false - for _, n1 := range n.List.Slice() { - hasbyte = hasbyte || n1.Op == ir.OBYTES2STR - haslit = haslit || n1.Op == ir.OLITERAL && len(n1.StringVal()) != 0 + for _, n1 := range n.List().Slice() { + hasbyte = hasbyte || n1.Op() == ir.OBYTES2STR + haslit = haslit || n1.Op() == ir.OLITERAL && len(n1.StringVal()) != 0 } if haslit && hasbyte { - for _, n2 := range n.List.Slice() { - if n2.Op == ir.OBYTES2STR { - n2.Op = ir.OBYTES2STRTMP + for _, n2 := range n.List().Slice() { + if n2.Op() == ir.OBYTES2STR { + n2.SetOp(ir.OBYTES2STRTMP) } } } case ir.OINDEXMAP: - n.Left = o.expr(n.Left, nil) - n.Right = o.expr(n.Right, nil) + n.SetLeft(o.expr(n.Left(), nil)) + n.SetRight(o.expr(n.Right(), nil)) needCopy := false if !n.IndexMapLValue() { @@ -1120,7 +1120,7 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { // can not be changed before the map index by forcing // the map index to happen immediately following the // conversions. See copyExpr a few lines below. - needCopy = mapKeyReplaceStrConv(n.Right) + needCopy = mapKeyReplaceStrConv(n.Right()) if instrumenting { // Race detector needs the copy so it can @@ -1130,37 +1130,37 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { } // key must be addressable - n.Right = o.mapKeyTemp(n.Left.Type, n.Right) + n.SetRight(o.mapKeyTemp(n.Left().Type(), n.Right())) if needCopy { - n = o.copyExpr(n, n.Type, false) + n = o.copyExpr(n, n.Type(), false) } // concrete type (not interface) argument might need an addressable // temporary to pass to the runtime conversion routine. case ir.OCONVIFACE: - n.Left = o.expr(n.Left, nil) - if n.Left.Type.IsInterface() { + n.SetLeft(o.expr(n.Left(), nil)) + if n.Left().Type().IsInterface() { break } - if _, needsaddr := convFuncName(n.Left.Type, n.Type); needsaddr || isStaticCompositeLiteral(n.Left) { + if _, needsaddr := convFuncName(n.Left().Type(), n.Type()); needsaddr || isStaticCompositeLiteral(n.Left()) { // Need a temp if we need to pass the address to the conversion function. // We also process static composite literal node here, making a named static global // whose address we can put directly in an interface (see OCONVIFACE case in walk). - n.Left = o.addrTemp(n.Left) + n.SetLeft(o.addrTemp(n.Left())) } case ir.OCONVNOP: - if n.Type.IsKind(types.TUNSAFEPTR) && n.Left.Type.IsKind(types.TUINTPTR) && (n.Left.Op == ir.OCALLFUNC || n.Left.Op == ir.OCALLINTER || n.Left.Op == ir.OCALLMETH) { + if n.Type().IsKind(types.TUNSAFEPTR) && n.Left().Type().IsKind(types.TUINTPTR) && (n.Left().Op() == ir.OCALLFUNC || n.Left().Op() == ir.OCALLINTER || n.Left().Op() == ir.OCALLMETH) { // When reordering unsafe.Pointer(f()) into a separate // statement, the conversion and function call must stay // together. See golang.org/issue/15329. - o.init(n.Left) - o.call(n.Left) - if lhs == nil || lhs.Op != ir.ONAME || instrumenting { - n = o.copyExpr(n, n.Type, false) + o.init(n.Left()) + o.call(n.Left()) + if lhs == nil || lhs.Op() != ir.ONAME || instrumenting { + n = o.copyExpr(n, n.Type(), false) } } else { - n.Left = o.expr(n.Left, nil) + n.SetLeft(o.expr(n.Left(), nil)) } case ir.OANDAND, ir.OOROR: @@ -1173,10 +1173,10 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { // } // ... = r - r := o.newTemp(n.Type, false) + r := o.newTemp(n.Type(), false) // Evaluate left-hand side. - lhs := o.expr(n.Left, nil) + lhs := o.expr(n.Left(), nil) o.out = append(o.out, typecheck(ir.Nod(ir.OAS, r, lhs), ctxStmt)) // Evaluate right-hand side, save generated code. @@ -1184,7 +1184,7 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { o.out = nil t := o.markTemp() o.edge() - rhs := o.expr(n.Right, nil) + rhs := o.expr(n.Right(), nil) o.out = append(o.out, typecheck(ir.Nod(ir.OAS, r, rhs), ctxStmt)) o.cleanTemp(t) gen := o.out @@ -1192,10 +1192,10 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { // If left-hand side doesn't cause a short-circuit, issue right-hand side. nif := ir.Nod(ir.OIF, r, nil) - if n.Op == ir.OANDAND { - nif.Nbody.Set(gen) + if n.Op() == ir.OANDAND { + nif.PtrBody().Set(gen) } else { - nif.Rlist.Set(gen) + nif.PtrRlist().Set(gen) } o.out = append(o.out, nif) n = r @@ -1221,30 +1221,30 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { if isRuneCount(n) { // len([]rune(s)) is rewritten to runtime.countrunes(s) later. - n.Left.Left = o.expr(n.Left.Left, nil) + n.Left().SetLeft(o.expr(n.Left().Left(), nil)) } else { o.call(n) } - if lhs == nil || lhs.Op != ir.ONAME || instrumenting { - n = o.copyExpr(n, n.Type, false) + if lhs == nil || lhs.Op() != ir.ONAME || instrumenting { + n = o.copyExpr(n, n.Type(), false) } case ir.OAPPEND: // Check for append(x, make([]T, y)...) . if isAppendOfMake(n) { - n.List.SetFirst(o.expr(n.List.First(), nil)) // order x - n.List.Second().Left = o.expr(n.List.Second().Left, nil) // order y + n.List().SetFirst(o.expr(n.List().First(), nil)) // order x + n.List().Second().SetLeft(o.expr(n.List().Second().Left(), nil)) // order y } else { - o.exprList(n.List) + o.exprList(n.List()) } - if lhs == nil || lhs.Op != ir.ONAME && !samesafeexpr(lhs, n.List.First()) { - n = o.copyExpr(n, n.Type, false) + if lhs == nil || lhs.Op() != ir.ONAME && !samesafeexpr(lhs, n.List().First()) { + n = o.copyExpr(n, n.Type(), false) } case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR: - n.Left = o.expr(n.Left, nil) + n.SetLeft(o.expr(n.Left(), nil)) low, high, max := n.SliceBounds() low = o.expr(low, nil) low = o.cheapExpr(low) @@ -1253,25 +1253,25 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { max = o.expr(max, nil) max = o.cheapExpr(max) n.SetSliceBounds(low, high, max) - if lhs == nil || lhs.Op != ir.ONAME && !samesafeexpr(lhs, n.Left) { - n = o.copyExpr(n, n.Type, false) + if lhs == nil || lhs.Op() != ir.ONAME && !samesafeexpr(lhs, n.Left()) { + n = o.copyExpr(n, n.Type(), false) } case ir.OCLOSURE: - if n.Transient() && n.Func.ClosureVars.Len() > 0 { + if n.Transient() && n.Func().ClosureVars.Len() > 0 { prealloc[n] = o.newTemp(closureType(n), false) } case ir.OSLICELIT, ir.OCALLPART: - n.Left = o.expr(n.Left, nil) - n.Right = o.expr(n.Right, nil) - o.exprList(n.List) - o.exprList(n.Rlist) + n.SetLeft(o.expr(n.Left(), nil)) + n.SetRight(o.expr(n.Right(), nil)) + o.exprList(n.List()) + o.exprList(n.Rlist()) if n.Transient() { var t *types.Type - switch n.Op { + switch n.Op() { case ir.OSLICELIT: - t = types.NewArray(n.Type.Elem(), n.Right.Int64Val()) + t = types.NewArray(n.Type().Elem(), n.Right().Int64Val()) case ir.OCALLPART: t = partialCallType(n) } @@ -1279,37 +1279,37 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { } case ir.ODOTTYPE, ir.ODOTTYPE2: - n.Left = o.expr(n.Left, nil) - if !isdirectiface(n.Type) || instrumenting { - n = o.copyExpr(n, n.Type, true) + n.SetLeft(o.expr(n.Left(), nil)) + if !isdirectiface(n.Type()) || instrumenting { + n = o.copyExpr(n, n.Type(), true) } case ir.ORECV: - n.Left = o.expr(n.Left, nil) - n = o.copyExpr(n, n.Type, true) + n.SetLeft(o.expr(n.Left(), nil)) + n = o.copyExpr(n, n.Type(), true) case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE: - n.Left = o.expr(n.Left, nil) - n.Right = o.expr(n.Right, nil) + n.SetLeft(o.expr(n.Left(), nil)) + n.SetRight(o.expr(n.Right(), nil)) - t := n.Left.Type + t := n.Left().Type() switch { case t.IsString(): // Mark string(byteSlice) arguments to reuse byteSlice backing // buffer during conversion. String comparison does not // memorize the strings for later use, so it is safe. - if n.Left.Op == ir.OBYTES2STR { - n.Left.Op = ir.OBYTES2STRTMP + if n.Left().Op() == ir.OBYTES2STR { + n.Left().SetOp(ir.OBYTES2STRTMP) } - if n.Right.Op == ir.OBYTES2STR { - n.Right.Op = ir.OBYTES2STRTMP + if n.Right().Op() == ir.OBYTES2STR { + n.Right().SetOp(ir.OBYTES2STRTMP) } case t.IsStruct() || t.IsArray(): // for complex comparisons, we need both args to be // addressable so we can pass them to the runtime. - n.Left = o.addrTemp(n.Left) - n.Right = o.addrTemp(n.Right) + n.SetLeft(o.addrTemp(n.Left())) + n.SetRight(o.addrTemp(n.Right())) } case ir.OMAPLIT: // Order map by converting: @@ -1327,15 +1327,15 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { // Without this special case, order would otherwise compute all // the keys and values before storing any of them to the map. // See issue 26552. - entries := n.List.Slice() + entries := n.List().Slice() statics := entries[:0] var dynamics []*ir.Node for _, r := range entries { - if r.Op != ir.OKEY { + if r.Op() != ir.OKEY { base.Fatalf("OMAPLIT entry not OKEY: %v\n", r) } - if !isStaticCompositeLiteral(r.Left) || !isStaticCompositeLiteral(r.Right) { + if !isStaticCompositeLiteral(r.Left()) || !isStaticCompositeLiteral(r.Right()) { dynamics = append(dynamics, r) continue } @@ -1343,21 +1343,21 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { // Recursively ordering some static entries can change them to dynamic; // e.g., OCONVIFACE nodes. See #31777. r = o.expr(r, nil) - if !isStaticCompositeLiteral(r.Left) || !isStaticCompositeLiteral(r.Right) { + if !isStaticCompositeLiteral(r.Left()) || !isStaticCompositeLiteral(r.Right()) { dynamics = append(dynamics, r) continue } statics = append(statics, r) } - n.List.Set(statics) + n.PtrList().Set(statics) if len(dynamics) == 0 { break } // Emit the creation of the map (with all its static entries). - m := o.newTemp(n.Type, false) + m := o.newTemp(n.Type(), false) as := ir.Nod(ir.OAS, m, n) typecheck(as, ctxStmt) o.stmt(as) @@ -1365,7 +1365,7 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { // Emit eval+insert of dynamic entries, one at a time. for _, r := range dynamics { - as := ir.Nod(ir.OAS, ir.Nod(ir.OINDEX, n, r.Left), r.Right) + as := ir.Nod(ir.OAS, ir.Nod(ir.OINDEX, n, r.Left()), r.Right()) typecheck(as, ctxStmt) // Note: this converts the OINDEX to an OINDEXMAP o.stmt(as) } @@ -1379,7 +1379,7 @@ func (o *Order) expr(n, lhs *ir.Node) *ir.Node { // including an explicit conversion if necessary. func okas(ok, val *ir.Node) *ir.Node { if !ir.IsBlank(ok) { - val = conv(val, ok.Type) + val = conv(val, ok.Type()) } return ir.Nod(ir.OAS, ok, val) } @@ -1395,10 +1395,10 @@ func okas(ok, val *ir.Node) *ir.Node { func (o *Order) as2(n *ir.Node) { tmplist := []*ir.Node{} left := []*ir.Node{} - for ni, l := range n.List.Slice() { + for ni, l := range n.List().Slice() { if !ir.IsBlank(l) { - tmp := o.newTemp(l.Type, l.Type.HasPointers()) - n.List.SetIndex(ni, tmp) + tmp := o.newTemp(l.Type(), l.Type().HasPointers()) + n.List().SetIndex(ni, tmp) tmplist = append(tmplist, tmp) left = append(left, l) } @@ -1407,8 +1407,8 @@ func (o *Order) as2(n *ir.Node) { o.out = append(o.out, n) as := ir.Nod(ir.OAS2, nil, nil) - as.List.Set(left) - as.Rlist.Set(tmplist) + as.PtrList().Set(left) + as.PtrRlist().Set(tmplist) as = typecheck(as, ctxStmt) o.stmt(as) } @@ -1417,27 +1417,27 @@ func (o *Order) as2(n *ir.Node) { // Just like as2, this also adds temporaries to ensure left-to-right assignment. func (o *Order) okAs2(n *ir.Node) { var tmp1, tmp2 *ir.Node - if !ir.IsBlank(n.List.First()) { - typ := n.Right.Type + if !ir.IsBlank(n.List().First()) { + typ := n.Right().Type() tmp1 = o.newTemp(typ, typ.HasPointers()) } - if !ir.IsBlank(n.List.Second()) { + if !ir.IsBlank(n.List().Second()) { tmp2 = o.newTemp(types.Types[types.TBOOL], false) } o.out = append(o.out, n) if tmp1 != nil { - r := ir.Nod(ir.OAS, n.List.First(), tmp1) + r := ir.Nod(ir.OAS, n.List().First(), tmp1) r = typecheck(r, ctxStmt) o.mapAssign(r) - n.List.SetFirst(tmp1) + n.List().SetFirst(tmp1) } if tmp2 != nil { - r := okas(n.List.Second(), tmp2) + r := okas(n.List().Second(), tmp2) r = typecheck(r, ctxStmt) o.mapAssign(r) - n.List.SetSecond(tmp2) + n.List().SetSecond(tmp2) } } diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go index 6e7922ca54..5827b5a7a6 100644 --- a/src/cmd/compile/internal/gc/pgen.go +++ b/src/cmd/compile/internal/gc/pgen.go @@ -28,30 +28,30 @@ var ( ) func emitptrargsmap(fn *ir.Node) { - if ir.FuncName(fn) == "_" || fn.Func.Nname.Sym.Linkname != "" { + if ir.FuncName(fn) == "_" || fn.Func().Nname.Sym().Linkname != "" { return } - lsym := base.Ctxt.Lookup(fn.Func.LSym.Name + ".args_stackmap") + lsym := base.Ctxt.Lookup(fn.Func().LSym.Name + ".args_stackmap") - nptr := int(fn.Type.ArgWidth() / int64(Widthptr)) + nptr := int(fn.Type().ArgWidth() / int64(Widthptr)) bv := bvalloc(int32(nptr) * 2) nbitmap := 1 - if fn.Type.NumResults() > 0 { + if fn.Type().NumResults() > 0 { nbitmap = 2 } off := duint32(lsym, 0, uint32(nbitmap)) off = duint32(lsym, off, uint32(bv.n)) if ir.IsMethod(fn) { - onebitwalktype1(fn.Type.Recvs(), 0, bv) + onebitwalktype1(fn.Type().Recvs(), 0, bv) } - if fn.Type.NumParams() > 0 { - onebitwalktype1(fn.Type.Params(), 0, bv) + if fn.Type().NumParams() > 0 { + onebitwalktype1(fn.Type().Params(), 0, bv) } off = dbvec(lsym, off, bv) - if fn.Type.NumResults() > 0 { - onebitwalktype1(fn.Type.Results(), 0, bv) + if fn.Type().NumResults() > 0 { + onebitwalktype1(fn.Type().Results(), 0, bv) off = dbvec(lsym, off, bv) } @@ -74,30 +74,30 @@ func cmpstackvarlt(a, b *ir.Node) bool { } if a.Class() != ir.PAUTO { - return a.Xoffset < b.Xoffset + return a.Offset() < b.Offset() } - if a.Name.Used() != b.Name.Used() { - return a.Name.Used() + if a.Name().Used() != b.Name().Used() { + return a.Name().Used() } - ap := a.Type.HasPointers() - bp := b.Type.HasPointers() + ap := a.Type().HasPointers() + bp := b.Type().HasPointers() if ap != bp { return ap } - ap = a.Name.Needzero() - bp = b.Name.Needzero() + ap = a.Name().Needzero() + bp = b.Name().Needzero() if ap != bp { return ap } - if a.Type.Width != b.Type.Width { - return a.Type.Width > b.Type.Width + if a.Type().Width != b.Type().Width { + return a.Type().Width > b.Type().Width } - return a.Sym.Name < b.Sym.Name + return a.Sym().Name < b.Sym().Name } // byStackvar implements sort.Interface for []*Node using cmpstackvarlt. @@ -110,18 +110,18 @@ func (s byStackVar) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s *ssafn) AllocFrame(f *ssa.Func) { s.stksize = 0 s.stkptrsize = 0 - fn := s.curfn.Func + fn := s.curfn.Func() // Mark the PAUTO's unused. for _, ln := range fn.Dcl { if ln.Class() == ir.PAUTO { - ln.Name.SetUsed(false) + ln.Name().SetUsed(false) } } for _, l := range f.RegAlloc { if ls, ok := l.(ssa.LocalSlot); ok { - ls.N.Name.SetUsed(true) + ls.N.Name().SetUsed(true) } } @@ -133,10 +133,10 @@ func (s *ssafn) AllocFrame(f *ssa.Func) { case ir.PPARAM, ir.PPARAMOUT: // Don't modify nodfp; it is a global. if n != nodfp { - n.Name.SetUsed(true) + n.Name().SetUsed(true) } case ir.PAUTO: - n.Name.SetUsed(true) + n.Name().SetUsed(true) } } if !scratchUsed { @@ -155,16 +155,16 @@ func (s *ssafn) AllocFrame(f *ssa.Func) { // Reassign stack offsets of the locals that are used. lastHasPtr := false for i, n := range fn.Dcl { - if n.Op != ir.ONAME || n.Class() != ir.PAUTO { + if n.Op() != ir.ONAME || n.Class() != ir.PAUTO { continue } - if !n.Name.Used() { + if !n.Name().Used() { fn.Dcl = fn.Dcl[:i] break } - dowidth(n.Type) - w := n.Type.Width + dowidth(n.Type()) + w := n.Type().Width if w >= thearch.MAXWIDTH || w < 0 { base.Fatalf("bad width") } @@ -176,8 +176,8 @@ func (s *ssafn) AllocFrame(f *ssa.Func) { w = 1 } s.stksize += w - s.stksize = Rnd(s.stksize, int64(n.Type.Align)) - if n.Type.HasPointers() { + s.stksize = Rnd(s.stksize, int64(n.Type().Align)) + if n.Type().HasPointers() { s.stkptrsize = s.stksize lastHasPtr = true } else { @@ -186,7 +186,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) { if thearch.LinkArch.InFamily(sys.MIPS, sys.MIPS64, sys.ARM, sys.ARM64, sys.PPC64, sys.S390X) { s.stksize = Rnd(s.stksize, int64(Widthptr)) } - n.Xoffset = -s.stksize + n.SetOffset(-s.stksize) } s.stksize = Rnd(s.stksize, int64(Widthreg)) @@ -195,10 +195,10 @@ func (s *ssafn) AllocFrame(f *ssa.Func) { func funccompile(fn *ir.Node) { if Curfn != nil { - base.Fatalf("funccompile %v inside %v", fn.Func.Nname.Sym, Curfn.Func.Nname.Sym) + base.Fatalf("funccompile %v inside %v", fn.Func().Nname.Sym(), Curfn.Func().Nname.Sym()) } - if fn.Type == nil { + if fn.Type() == nil { if base.Errors() == 0 { base.Fatalf("funccompile missing type") } @@ -206,11 +206,11 @@ func funccompile(fn *ir.Node) { } // assign parameter offsets - dowidth(fn.Type) + dowidth(fn.Type()) - if fn.Nbody.Len() == 0 { + if fn.Body().Len() == 0 { // Initialize ABI wrappers if necessary. - initLSym(fn.Func, false) + initLSym(fn.Func(), false) emitptrargsmap(fn) return } @@ -234,7 +234,7 @@ func compile(fn *ir.Node) { // Set up the function's LSym early to avoid data races with the assemblers. // Do this before walk, as walk needs the LSym to set attributes/relocations // (e.g. in markTypeUsedInInterface). - initLSym(fn.Func, true) + initLSym(fn.Func(), true) walk(fn) if base.Errors() > errorsBefore { @@ -259,15 +259,15 @@ func compile(fn *ir.Node) { // be types of stack objects. We need to do this here // because symbols must be allocated before the parallel // phase of the compiler. - for _, n := range fn.Func.Dcl { + for _, n := range fn.Func().Dcl { switch n.Class() { case ir.PPARAM, ir.PPARAMOUT, ir.PAUTO: - if livenessShouldTrack(n) && n.Name.Addrtaken() { - dtypesym(n.Type) + if livenessShouldTrack(n) && n.Name().Addrtaken() { + dtypesym(n.Type()) // Also make sure we allocate a linker symbol // for the stack object data, for the same reason. - if fn.Func.LSym.Func().StackObjects == nil { - fn.Func.LSym.Func().StackObjects = base.Ctxt.Lookup(fn.Func.LSym.Name + ".stkobj") + if fn.Func().LSym.Func().StackObjects == nil { + fn.Func().LSym.Func().StackObjects = base.Ctxt.Lookup(fn.Func().LSym.Name + ".stkobj") } } } @@ -300,13 +300,13 @@ func compilenow(fn *ir.Node) bool { // inline candidate but then never inlined (presumably because we // found no call sites). func isInlinableButNotInlined(fn *ir.Node) bool { - if fn.Func.Nname.Func.Inl == nil { + if fn.Func().Nname.Func().Inl == nil { return false } - if fn.Sym == nil { + if fn.Sym() == nil { return true } - return !fn.Sym.Linksym().WasInlined() + return !fn.Sym().Linksym().WasInlined() } const maxStackSize = 1 << 30 @@ -318,9 +318,9 @@ const maxStackSize = 1 << 30 func compileSSA(fn *ir.Node, worker int) { f := buildssa(fn, worker) // Note: check arg size to fix issue 25507. - if f.Frontend().(*ssafn).stksize >= maxStackSize || fn.Type.ArgWidth() >= maxStackSize { + if f.Frontend().(*ssafn).stksize >= maxStackSize || fn.Type().ArgWidth() >= maxStackSize { largeStackFramesMu.Lock() - largeStackFrames = append(largeStackFrames, largeStack{locals: f.Frontend().(*ssafn).stksize, args: fn.Type.ArgWidth(), pos: fn.Pos}) + largeStackFrames = append(largeStackFrames, largeStack{locals: f.Frontend().(*ssafn).stksize, args: fn.Type().ArgWidth(), pos: fn.Pos()}) largeStackFramesMu.Unlock() return } @@ -336,14 +336,14 @@ func compileSSA(fn *ir.Node, worker int) { if pp.Text.To.Offset >= maxStackSize { largeStackFramesMu.Lock() locals := f.Frontend().(*ssafn).stksize - largeStackFrames = append(largeStackFrames, largeStack{locals: locals, args: fn.Type.ArgWidth(), callee: pp.Text.To.Offset - locals, pos: fn.Pos}) + largeStackFrames = append(largeStackFrames, largeStack{locals: locals, args: fn.Type().ArgWidth(), callee: pp.Text.To.Offset - locals, pos: fn.Pos()}) largeStackFramesMu.Unlock() return } pp.Flush() // assemble, fill in boilerplate, etc. // fieldtrack must be called after pp.Flush. See issue 20014. - fieldtrack(pp.Text.From.Sym, fn.Func.FieldTrack) + fieldtrack(pp.Text.From.Sym, fn.Func().FieldTrack) } func init() { @@ -371,7 +371,7 @@ func compileFunctions() { // since they're most likely to be the slowest. // This helps avoid stragglers. sort.Slice(compilequeue, func(i, j int) bool { - return compilequeue[i].Nbody.Len() > compilequeue[j].Nbody.Len() + return compilequeue[i].Body().Len() > compilequeue[j].Body().Len() }) } var wg sync.WaitGroup @@ -399,8 +399,8 @@ func compileFunctions() { func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.Scope, dwarf.InlCalls) { fn := curfn.(*ir.Node) - if fn.Func.Nname != nil { - if expect := fn.Func.Nname.Sym.Linksym(); fnsym != expect { + if fn.Func().Nname != nil { + if expect := fn.Func().Nname.Sym().Linksym(); fnsym != expect { base.Fatalf("unexpected fnsym: %v != %v", fnsym, expect) } } @@ -430,18 +430,18 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S // // These two adjustments keep toolstash -cmp working for now. // Deciding the right answer is, as they say, future work. - isODCLFUNC := fn.Op == ir.ODCLFUNC + isODCLFUNC := fn.Op() == ir.ODCLFUNC var apdecls []*ir.Node // Populate decls for fn. if isODCLFUNC { - for _, n := range fn.Func.Dcl { - if n.Op != ir.ONAME { // might be OTYPE or OLITERAL + for _, n := range fn.Func().Dcl { + if n.Op() != ir.ONAME { // might be OTYPE or OLITERAL continue } switch n.Class() { case ir.PAUTO: - if !n.Name.Used() { + if !n.Name().Used() { // Text == nil -> generating abstract function if fnsym.Func().Text != nil { base.Fatalf("debuginfo unused node (AllocFrame should truncate fn.Func.Dcl)") @@ -457,7 +457,7 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S } } - decls, dwarfVars := createDwarfVars(fnsym, isODCLFUNC, fn.Func, apdecls) + decls, dwarfVars := createDwarfVars(fnsym, isODCLFUNC, fn.Func(), apdecls) // For each type referenced by the functions auto vars but not // already referenced by a dwarf var, attach an R_USETYPE relocation to @@ -478,7 +478,7 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S var varScopes []ir.ScopeID for _, decl := range decls { pos := declPos(decl) - varScopes = append(varScopes, findScope(fn.Func.Marks, pos)) + varScopes = append(varScopes, findScope(fn.Func().Marks, pos)) } scopes := assembleScopes(fnsym, fn, dwarfVars, varScopes) @@ -490,7 +490,7 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S } func declPos(decl *ir.Node) src.XPos { - if decl.Name.Defn != nil && (decl.Name.Captured() || decl.Name.Byval()) { + if decl.Name().Defn != nil && (decl.Name().Captured() || decl.Name().Byval()) { // It's not clear which position is correct for captured variables here: // * decl.Pos is the wrong position for captured variables, in the inner // function, but it is the right position in the outer function. @@ -505,9 +505,9 @@ func declPos(decl *ir.Node) src.XPos { // case statement. // This code is probably wrong for type switch variables that are also // captured. - return decl.Name.Defn.Pos + return decl.Name().Defn.Pos() } - return decl.Pos + return decl.Pos() } // createSimpleVars creates a DWARF entry for every variable declared in the @@ -530,7 +530,7 @@ func createSimpleVars(fnsym *obj.LSym, apDecls []*ir.Node) ([]*ir.Node, []*dwarf func createSimpleVar(fnsym *obj.LSym, n *ir.Node) *dwarf.Var { var abbrev int - offs := n.Xoffset + offs := n.Offset() switch n.Class() { case ir.PAUTO: @@ -550,22 +550,22 @@ func createSimpleVar(fnsym *obj.LSym, n *ir.Node) *dwarf.Var { base.Fatalf("createSimpleVar unexpected class %v for node %v", n.Class(), n) } - typename := dwarf.InfoPrefix + typesymname(n.Type) + typename := dwarf.InfoPrefix + typesymname(n.Type()) delete(fnsym.Func().Autot, ngotype(n).Linksym()) inlIndex := 0 if base.Flag.GenDwarfInl > 1 { - if n.Name.InlFormal() || n.Name.InlLocal() { - inlIndex = posInlIndex(n.Pos) + 1 - if n.Name.InlFormal() { + if n.Name().InlFormal() || n.Name().InlLocal() { + inlIndex = posInlIndex(n.Pos()) + 1 + if n.Name().InlFormal() { abbrev = dwarf.DW_ABRV_PARAM } } } declpos := base.Ctxt.InnermostPos(declPos(n)) return &dwarf.Var{ - Name: n.Sym.Name, + Name: n.Sym().Name, IsReturnValue: n.Class() == ir.PPARAMOUT, - IsInlFormal: n.Name.InlFormal(), + IsInlFormal: n.Name().InlFormal(), Abbrev: abbrev, StackOffset: int32(offs), Type: base.Ctxt.Lookup(typename), @@ -637,11 +637,11 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir if _, found := selected[n]; found { continue } - c := n.Sym.Name[0] - if c == '.' || n.Type.IsUntyped() { + c := n.Sym().Name[0] + if c == '.' || n.Type().IsUntyped() { continue } - if n.Class() == ir.PPARAM && !canSSAType(n.Type) { + if n.Class() == ir.PPARAM && !canSSAType(n.Type()) { // SSA-able args get location lists, and may move in and // out of registers, so those are handled elsewhere. // Autos and named output params seem to get handled @@ -653,7 +653,7 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir decls = append(decls, n) continue } - typename := dwarf.InfoPrefix + typesymname(n.Type) + typename := dwarf.InfoPrefix + typesymname(n.Type()) decls = append(decls, n) abbrev := dwarf.DW_ABRV_AUTO_LOCLIST isReturnValue := (n.Class() == ir.PPARAMOUT) @@ -667,7 +667,7 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir // misleading location for the param (we want pointer-to-heap // and not stack). // TODO(thanm): generate a better location expression - stackcopy := n.Name.Param.Stackcopy + stackcopy := n.Name().Param.Stackcopy if stackcopy != nil && (stackcopy.Class() == ir.PPARAM || stackcopy.Class() == ir.PPARAMOUT) { abbrev = dwarf.DW_ABRV_PARAM_LOCLIST isReturnValue = (stackcopy.Class() == ir.PPARAMOUT) @@ -675,19 +675,19 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir } inlIndex := 0 if base.Flag.GenDwarfInl > 1 { - if n.Name.InlFormal() || n.Name.InlLocal() { - inlIndex = posInlIndex(n.Pos) + 1 - if n.Name.InlFormal() { + if n.Name().InlFormal() || n.Name().InlLocal() { + inlIndex = posInlIndex(n.Pos()) + 1 + if n.Name().InlFormal() { abbrev = dwarf.DW_ABRV_PARAM_LOCLIST } } } - declpos := base.Ctxt.InnermostPos(n.Pos) + declpos := base.Ctxt.InnermostPos(n.Pos()) vars = append(vars, &dwarf.Var{ - Name: n.Sym.Name, + Name: n.Sym().Name, IsReturnValue: isReturnValue, Abbrev: abbrev, - StackOffset: int32(n.Xoffset), + StackOffset: int32(n.Offset()), Type: base.Ctxt.Lookup(typename), DeclFile: declpos.RelFilename(), DeclLine: declpos.RelLine(), @@ -711,11 +711,11 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir func preInliningDcls(fnsym *obj.LSym) []*ir.Node { fn := base.Ctxt.DwFixups.GetPrecursorFunc(fnsym).(*ir.Node) var rdcl []*ir.Node - for _, n := range fn.Func.Inl.Dcl { - c := n.Sym.Name[0] + for _, n := range fn.Func().Inl.Dcl { + c := n.Sym().Name[0] // Avoid reporting "_" parameters, since if there are more than // one, it can result in a collision later on, as in #23179. - if unversion(n.Sym.Name) == "_" || c == '.' || n.Type.IsUntyped() { + if unversion(n.Sym().Name) == "_" || c == '.' || n.Type().IsUntyped() { continue } rdcl = append(rdcl, n) @@ -741,7 +741,7 @@ func stackOffset(slot ssa.LocalSlot) int32 { case ir.PPARAM, ir.PPARAMOUT: off += base.Ctxt.FixedFrameSize() } - return int32(off + n.Xoffset + slot.Off) + return int32(off + n.Offset() + slot.Off) } // createComplexVar builds a single DWARF variable entry and location list. @@ -764,18 +764,18 @@ func createComplexVar(fnsym *obj.LSym, fn *ir.Func, varID ssa.VarID) *dwarf.Var typename := dwarf.InfoPrefix + gotype.Name[len("type."):] inlIndex := 0 if base.Flag.GenDwarfInl > 1 { - if n.Name.InlFormal() || n.Name.InlLocal() { - inlIndex = posInlIndex(n.Pos) + 1 - if n.Name.InlFormal() { + if n.Name().InlFormal() || n.Name().InlLocal() { + inlIndex = posInlIndex(n.Pos()) + 1 + if n.Name().InlFormal() { abbrev = dwarf.DW_ABRV_PARAM_LOCLIST } } } - declpos := base.Ctxt.InnermostPos(n.Pos) + declpos := base.Ctxt.InnermostPos(n.Pos()) dvar := &dwarf.Var{ - Name: n.Sym.Name, + Name: n.Sym().Name, IsReturnValue: n.Class() == ir.PPARAMOUT, - IsInlFormal: n.Name.InlFormal(), + IsInlFormal: n.Name().InlFormal(), Abbrev: abbrev, Type: base.Ctxt.Lookup(typename), // The stack offset is used as a sorting key, so for decomposed diff --git a/src/cmd/compile/internal/gc/pgen_test.go b/src/cmd/compile/internal/gc/pgen_test.go index 9f1f00d46a..efdffe0256 100644 --- a/src/cmd/compile/internal/gc/pgen_test.go +++ b/src/cmd/compile/internal/gc/pgen_test.go @@ -27,12 +27,12 @@ func typeWithPointers() *types.Type { } func markUsed(n *ir.Node) *ir.Node { - n.Name.SetUsed(true) + n.Name().SetUsed(true) return n } func markNeedZero(n *ir.Node) *ir.Node { - n.Name.SetNeedzero(true) + n.Name().SetNeedzero(true) return n } @@ -43,8 +43,8 @@ func TestCmpstackvar(t *testing.T) { s = &types.Sym{Name: "."} } n := NewName(s) - n.Type = t - n.Xoffset = xoffset + n.SetType(t) + n.SetOffset(xoffset) n.SetClass(cl) return n } @@ -158,8 +158,8 @@ func TestCmpstackvar(t *testing.T) { func TestStackvarSort(t *testing.T) { nod := func(xoffset int64, t *types.Type, s *types.Sym, cl ir.Class) *ir.Node { n := NewName(s) - n.Type = t - n.Xoffset = xoffset + n.SetType(t) + n.SetOffset(xoffset) n.SetClass(cl) return n } diff --git a/src/cmd/compile/internal/gc/plive.go b/src/cmd/compile/internal/gc/plive.go index f089588466..c1e523f7a0 100644 --- a/src/cmd/compile/internal/gc/plive.go +++ b/src/cmd/compile/internal/gc/plive.go @@ -207,14 +207,14 @@ type progeffectscache struct { // nor do we care about empty structs (handled by the pointer check), // nor do we care about the fake PAUTOHEAP variables. func livenessShouldTrack(n *ir.Node) bool { - return n.Op == ir.ONAME && (n.Class() == ir.PAUTO || n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) && n.Type.HasPointers() + return n.Op() == ir.ONAME && (n.Class() == ir.PAUTO || n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) && n.Type().HasPointers() } // getvariables returns the list of on-stack variables that we need to track // and a map for looking up indices by *Node. func getvariables(fn *ir.Node) ([]*ir.Node, map[*ir.Node]int32) { var vars []*ir.Node - for _, n := range fn.Func.Dcl { + for _, n := range fn.Func().Dcl { if livenessShouldTrack(n) { vars = append(vars, n) } @@ -272,7 +272,7 @@ const ( // If v does not affect any tracked variables, it returns -1, 0. func (lv *Liveness) valueEffects(v *ssa.Value) (int32, liveEffect) { n, e := affectedNode(v) - if e == 0 || n == nil || n.Op != ir.ONAME { // cheapest checks first + if e == 0 || n == nil || n.Op() != ir.ONAME { // cheapest checks first return -1, 0 } @@ -282,7 +282,7 @@ func (lv *Liveness) valueEffects(v *ssa.Value) (int32, liveEffect) { // variable" ICEs (issue 19632). switch v.Op { case ssa.OpVarDef, ssa.OpVarKill, ssa.OpVarLive, ssa.OpKeepAlive: - if !n.Name.Used() { + if !n.Name().Used() { return -1, 0 } } @@ -297,7 +297,7 @@ func (lv *Liveness) valueEffects(v *ssa.Value) (int32, liveEffect) { if e&(ssa.SymRead|ssa.SymAddr) != 0 { effect |= uevar } - if e&ssa.SymWrite != 0 && (!isfat(n.Type) || v.Op == ssa.OpVarDef) { + if e&ssa.SymWrite != 0 && (!isfat(n.Type()) || v.Op == ssa.OpVarDef) { effect |= varkill } @@ -491,10 +491,10 @@ func (lv *Liveness) pointerMap(liveout bvec, vars []*ir.Node, args, locals bvec) node := vars[i] switch node.Class() { case ir.PAUTO: - onebitwalktype1(node.Type, node.Xoffset+lv.stkptrsize, locals) + onebitwalktype1(node.Type(), node.Offset()+lv.stkptrsize, locals) case ir.PPARAM, ir.PPARAMOUT: - onebitwalktype1(node.Type, node.Xoffset, args) + onebitwalktype1(node.Type(), node.Offset(), args) } } } @@ -788,14 +788,14 @@ func (lv *Liveness) epilogue() { // pointers to copy values back to the stack). // TODO: if the output parameter is heap-allocated, then we // don't need to keep the stack copy live? - if lv.fn.Func.HasDefer() { + if lv.fn.Func().HasDefer() { for i, n := range lv.vars { if n.Class() == ir.PPARAMOUT { - if n.Name.IsOutputParamHeapAddr() { + if n.Name().IsOutputParamHeapAddr() { // Just to be paranoid. Heap addresses are PAUTOs. base.Fatalf("variable %v both output param and heap output param", n) } - if n.Name.Param.Heapaddr != nil { + if n.Name().Param.Heapaddr != nil { // If this variable moved to the heap, then // its stack copy is not live. continue @@ -803,21 +803,21 @@ func (lv *Liveness) epilogue() { // Note: zeroing is handled by zeroResults in walk.go. livedefer.Set(int32(i)) } - if n.Name.IsOutputParamHeapAddr() { + if n.Name().IsOutputParamHeapAddr() { // This variable will be overwritten early in the function // prologue (from the result of a mallocgc) but we need to // zero it in case that malloc causes a stack scan. - n.Name.SetNeedzero(true) + n.Name().SetNeedzero(true) livedefer.Set(int32(i)) } - if n.Name.OpenDeferSlot() { + if n.Name().OpenDeferSlot() { // Open-coded defer args slots must be live // everywhere in a function, since a panic can // occur (almost) anywhere. Because it is live // everywhere, it must be zeroed on entry. livedefer.Set(int32(i)) // It was already marked as Needzero when created. - if !n.Name.Needzero() { + if !n.Name().Needzero() { base.Fatalf("all pointer-containing defer arg slots should have Needzero set") } } @@ -891,7 +891,7 @@ func (lv *Liveness) epilogue() { if n.Class() == ir.PPARAM { continue // ok } - base.Fatalf("bad live variable at entry of %v: %L", lv.fn.Func.Nname, n) + base.Fatalf("bad live variable at entry of %v: %L", lv.fn.Func().Nname, n) } // Record live variables. @@ -904,7 +904,7 @@ func (lv *Liveness) epilogue() { } // If we have an open-coded deferreturn call, make a liveness map for it. - if lv.fn.Func.OpenCodedDeferDisallowed() { + if lv.fn.Func().OpenCodedDeferDisallowed() { lv.livenessMap.deferreturn = LivenessDontCare } else { lv.livenessMap.deferreturn = LivenessIndex{ @@ -922,7 +922,7 @@ func (lv *Liveness) epilogue() { // input parameters. for j, n := range lv.vars { if n.Class() != ir.PPARAM && lv.stackMaps[0].Get(int32(j)) { - lv.f.Fatalf("%v %L recorded as live on entry", lv.fn.Func.Nname, n) + lv.f.Fatalf("%v %L recorded as live on entry", lv.fn.Func().Nname, n) } } } @@ -980,7 +980,7 @@ func (lv *Liveness) showlive(v *ssa.Value, live bvec) { return } - pos := lv.fn.Func.Nname.Pos + pos := lv.fn.Func().Nname.Pos() if v != nil { pos = v.Pos } @@ -1024,7 +1024,7 @@ func (lv *Liveness) printbvec(printed bool, name string, live bvec) bool { if !live.Get(int32(i)) { continue } - fmt.Printf("%s%s", comma, n.Sym.Name) + fmt.Printf("%s%s", comma, n.Sym().Name) comma = "," } return true @@ -1042,7 +1042,7 @@ func (lv *Liveness) printeffect(printed bool, name string, pos int32, x bool) bo } fmt.Printf("%s=", name) if x { - fmt.Printf("%s", lv.vars[pos].Sym.Name) + fmt.Printf("%s", lv.vars[pos].Sym().Name) } return true @@ -1090,7 +1090,7 @@ func (lv *Liveness) printDebug() { if b == lv.f.Entry { live := lv.stackMaps[0] - fmt.Printf("(%s) function entry\n", base.FmtPos(lv.fn.Func.Nname.Pos)) + fmt.Printf("(%s) function entry\n", base.FmtPos(lv.fn.Func().Nname.Pos())) fmt.Printf("\tlive=") printed = false for j, n := range lv.vars { @@ -1168,7 +1168,7 @@ func (lv *Liveness) emit() (argsSym, liveSym *obj.LSym) { for _, n := range lv.vars { switch n.Class() { case ir.PPARAM, ir.PPARAMOUT: - if maxArgNode == nil || n.Xoffset > maxArgNode.Xoffset { + if maxArgNode == nil || n.Offset() > maxArgNode.Offset() { maxArgNode = n } } @@ -1176,7 +1176,7 @@ func (lv *Liveness) emit() (argsSym, liveSym *obj.LSym) { // Next, find the offset of the largest pointer in the largest node. var maxArgs int64 if maxArgNode != nil { - maxArgs = maxArgNode.Xoffset + typeptrdata(maxArgNode.Type) + maxArgs = maxArgNode.Offset() + typeptrdata(maxArgNode.Type()) } // Size locals bitmaps to be stkptrsize sized. @@ -1266,7 +1266,7 @@ func liveness(e *ssafn, f *ssa.Func, pp *Progs) LivenessMap { } // Emit the live pointer map data structures - ls := e.curfn.Func.LSym + ls := e.curfn.Func().LSym fninfo := ls.Func() fninfo.GCArgs, fninfo.GCLocals = lv.emit() diff --git a/src/cmd/compile/internal/gc/racewalk.go b/src/cmd/compile/internal/gc/racewalk.go index d92749589f..5ab2821187 100644 --- a/src/cmd/compile/internal/gc/racewalk.go +++ b/src/cmd/compile/internal/gc/racewalk.go @@ -61,12 +61,12 @@ func ispkgin(pkgs []string) bool { } func instrument(fn *ir.Node) { - if fn.Func.Pragma&ir.Norace != 0 { + if fn.Func().Pragma&ir.Norace != 0 { return } if !base.Flag.Race || !ispkgin(norace_inst_pkgs) { - fn.Func.SetInstrumentBody(true) + fn.Func().SetInstrumentBody(true) } if base.Flag.Race { @@ -74,8 +74,8 @@ func instrument(fn *ir.Node) { base.Pos = src.NoXPos if thearch.LinkArch.Arch.Family != sys.AMD64 { - fn.Func.Enter.Prepend(mkcall("racefuncenterfp", nil, nil)) - fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil)) + fn.Func().Enter.Prepend(mkcall("racefuncenterfp", nil, nil)) + fn.Func().Exit.Append(mkcall("racefuncexit", nil, nil)) } else { // nodpc is the PC of the caller as extracted by @@ -84,11 +84,11 @@ func instrument(fn *ir.Node) { // work on arm or others that might support // race in the future. nodpc := ir.Copy(nodfp) - nodpc.Type = types.Types[types.TUINTPTR] - nodpc.Xoffset = int64(-Widthptr) - fn.Func.Dcl = append(fn.Func.Dcl, nodpc) - fn.Func.Enter.Prepend(mkcall("racefuncenter", nil, nil, nodpc)) - fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil)) + nodpc.SetType(types.Types[types.TUINTPTR]) + nodpc.SetOffset(int64(-Widthptr)) + fn.Func().Dcl = append(fn.Func().Dcl, nodpc) + fn.Func().Enter.Prepend(mkcall("racefuncenter", nil, nil, nodpc)) + fn.Func().Exit.Append(mkcall("racefuncexit", nil, nil)) } base.Pos = lno } diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go index edaec21f92..6a2a65c2df 100644 --- a/src/cmd/compile/internal/gc/range.go +++ b/src/cmd/compile/internal/gc/range.go @@ -27,7 +27,7 @@ func typecheckrange(n *ir.Node) { // second half of dance, the first half being typecheckrangeExpr n.SetTypecheck(1) - ls := n.List.Slice() + ls := n.List().Slice() for i1, n1 := range ls { if n1.Typecheck() == 0 { ls[i1] = typecheck(ls[i1], ctxExpr|ctxAssign) @@ -35,21 +35,21 @@ func typecheckrange(n *ir.Node) { } decldepth++ - typecheckslice(n.Nbody.Slice(), ctxStmt) + typecheckslice(n.Body().Slice(), ctxStmt) decldepth-- } func typecheckrangeExpr(n *ir.Node) { - n.Right = typecheck(n.Right, ctxExpr) + n.SetRight(typecheck(n.Right(), ctxExpr)) - t := n.Right.Type + t := n.Right().Type() if t == nil { return } // delicate little dance. see typecheckas2 - ls := n.List.Slice() + ls := n.List().Slice() for i1, n1 := range ls { - if n1.Name == nil || n1.Name.Defn != n { + if n1.Name() == nil || n1.Name().Defn != n { ls[i1] = typecheck(ls[i1], ctxExpr|ctxAssign) } } @@ -57,13 +57,13 @@ func typecheckrangeExpr(n *ir.Node) { if t.IsPtr() && t.Elem().IsArray() { t = t.Elem() } - n.Type = t + n.SetType(t) var t1, t2 *types.Type toomany := false switch t.Etype { default: - base.ErrorfAt(n.Pos, "cannot range over %L", n.Right) + base.ErrorfAt(n.Pos(), "cannot range over %L", n.Right()) return case types.TARRAY, types.TSLICE: @@ -76,13 +76,13 @@ func typecheckrangeExpr(n *ir.Node) { case types.TCHAN: if !t.ChanDir().CanRecv() { - base.ErrorfAt(n.Pos, "invalid operation: range %v (receive from send-only type %v)", n.Right, n.Right.Type) + base.ErrorfAt(n.Pos(), "invalid operation: range %v (receive from send-only type %v)", n.Right(), n.Right().Type()) return } t1 = t.Elem() t2 = nil - if n.List.Len() == 2 { + if n.List().Len() == 2 { toomany = true } @@ -91,16 +91,16 @@ func typecheckrangeExpr(n *ir.Node) { t2 = types.Runetype } - if n.List.Len() > 2 || toomany { - base.ErrorfAt(n.Pos, "too many variables in range") + if n.List().Len() > 2 || toomany { + base.ErrorfAt(n.Pos(), "too many variables in range") } var v1, v2 *ir.Node - if n.List.Len() != 0 { - v1 = n.List.First() + if n.List().Len() != 0 { + v1 = n.List().First() } - if n.List.Len() > 1 { - v2 = n.List.Second() + if n.List().Len() > 1 { + v2 = n.List().Second() } // this is not only an optimization but also a requirement in the spec. @@ -109,28 +109,28 @@ func typecheckrangeExpr(n *ir.Node) { // present." if ir.IsBlank(v2) { if v1 != nil { - n.List.Set1(v1) + n.PtrList().Set1(v1) } v2 = nil } if v1 != nil { - if v1.Name != nil && v1.Name.Defn == n { - v1.Type = t1 - } else if v1.Type != nil { - if op, why := assignop(t1, v1.Type); op == ir.OXXX { - base.ErrorfAt(n.Pos, "cannot assign type %v to %L in range%s", t1, v1, why) + if v1.Name() != nil && v1.Name().Defn == n { + v1.SetType(t1) + } else if v1.Type() != nil { + if op, why := assignop(t1, v1.Type()); op == ir.OXXX { + base.ErrorfAt(n.Pos(), "cannot assign type %v to %L in range%s", t1, v1, why) } } checkassign(n, v1) } if v2 != nil { - if v2.Name != nil && v2.Name.Defn == n { - v2.Type = t2 - } else if v2.Type != nil { - if op, why := assignop(t2, v2.Type); op == ir.OXXX { - base.ErrorfAt(n.Pos, "cannot assign type %v to %L in range%s", t2, v2, why) + if v2.Name() != nil && v2.Name().Defn == n { + v2.SetType(t2) + } else if v2.Type() != nil { + if op, why := assignop(t2, v2.Type()); op == ir.OXXX { + base.ErrorfAt(n.Pos(), "cannot assign type %v to %L in range%s", t2, v2, why) } } checkassign(n, v2) @@ -159,7 +159,7 @@ func cheapComputableIndex(width int64) bool { // the returned node. func walkrange(n *ir.Node) *ir.Node { if isMapClear(n) { - m := n.Right + m := n.Right() lno := setlineno(m) n = mapClear(m) base.Pos = lno @@ -173,20 +173,20 @@ func walkrange(n *ir.Node) *ir.Node { // hb: hidden bool // a, v1, v2: not hidden aggregate, val 1, 2 - t := n.Type + t := n.Type() - a := n.Right + a := n.Right() lno := setlineno(a) - n.Right = nil + n.SetRight(nil) var v1, v2 *ir.Node - l := n.List.Len() + l := n.List().Len() if l > 0 { - v1 = n.List.First() + v1 = n.List().First() } if l > 1 { - v2 = n.List.Second() + v2 = n.List().Second() } if ir.IsBlank(v2) { @@ -203,7 +203,7 @@ func walkrange(n *ir.Node) *ir.Node { // n.List has no meaning anymore, clear it // to avoid erroneous processing by racewalk. - n.List.Set(nil) + n.PtrList().Set(nil) var ifGuard *ir.Node @@ -230,8 +230,8 @@ func walkrange(n *ir.Node) *ir.Node { init = append(init, ir.Nod(ir.OAS, hv1, nil)) init = append(init, ir.Nod(ir.OAS, hn, ir.Nod(ir.OLEN, ha, nil))) - n.Left = ir.Nod(ir.OLT, hv1, hn) - n.Right = ir.Nod(ir.OAS, hv1, ir.Nod(ir.OADD, hv1, nodintconst(1))) + n.SetLeft(ir.Nod(ir.OLT, hv1, hn)) + n.SetRight(ir.Nod(ir.OAS, hv1, ir.Nod(ir.OADD, hv1, nodintconst(1)))) // for range ha { body } if v1 == nil { @@ -245,15 +245,15 @@ func walkrange(n *ir.Node) *ir.Node { } // for v1, v2 := range ha { body } - if cheapComputableIndex(n.Type.Elem().Width) { + if cheapComputableIndex(n.Type().Elem().Width) { // v1, v2 = hv1, ha[hv1] tmp := ir.Nod(ir.OINDEX, ha, hv1) tmp.SetBounded(true) // Use OAS2 to correctly handle assignments // of the form "v1, a[v1] := range". a := ir.Nod(ir.OAS2, nil, nil) - a.List.Set2(v1, v2) - a.Rlist.Set2(hv1, tmp) + a.PtrList().Set2(v1, v2) + a.PtrRlist().Set2(hv1, tmp) body = []*ir.Node{a} break } @@ -271,10 +271,10 @@ func walkrange(n *ir.Node) *ir.Node { // elimination on the index variable (see #20711). // Enhance the prove pass to understand this. ifGuard = ir.Nod(ir.OIF, nil, nil) - ifGuard.Left = ir.Nod(ir.OLT, hv1, hn) + ifGuard.SetLeft(ir.Nod(ir.OLT, hv1, hn)) translatedLoopOp = ir.OFORUNTIL - hp := temp(types.NewPtr(n.Type.Elem())) + hp := temp(types.NewPtr(n.Type().Elem())) tmp := ir.Nod(ir.OINDEX, ha, nodintconst(0)) tmp.SetBounded(true) init = append(init, ir.Nod(ir.OAS, hp, ir.Nod(ir.OADDR, tmp, nil))) @@ -282,8 +282,8 @@ func walkrange(n *ir.Node) *ir.Node { // Use OAS2 to correctly handle assignments // of the form "v1, a[v1] := range". a := ir.Nod(ir.OAS2, nil, nil) - a.List.Set2(v1, v2) - a.Rlist.Set2(hv1, ir.Nod(ir.ODEREF, hp, nil)) + a.PtrList().Set2(v1, v2) + a.PtrRlist().Set2(hv1, ir.Nod(ir.ODEREF, hp, nil)) body = append(body, a) // Advance pointer as part of the late increment. @@ -293,7 +293,7 @@ func walkrange(n *ir.Node) *ir.Node { // end of the allocation. a = ir.Nod(ir.OAS, hp, addptr(hp, t.Elem().Width)) a = typecheck(a, ctxStmt) - n.List.Set1(a) + n.PtrList().Set1(a) case types.TMAP: // order.stmt allocated the iterator for us. @@ -301,8 +301,8 @@ func walkrange(n *ir.Node) *ir.Node { ha := a hit := prealloc[n] - th := hit.Type - n.Left = nil + th := hit.Type() + n.SetLeft(nil) keysym := th.Field(0).Sym // depends on layout of iterator struct. See reflect.go:hiter elemsym := th.Field(1).Sym // ditto @@ -310,11 +310,11 @@ func walkrange(n *ir.Node) *ir.Node { fn = substArgTypes(fn, t.Key(), t.Elem(), th) init = append(init, mkcall1(fn, nil, nil, typename(t), ha, ir.Nod(ir.OADDR, hit, nil))) - n.Left = ir.Nod(ir.ONE, nodSym(ir.ODOT, hit, keysym), nodnil()) + n.SetLeft(ir.Nod(ir.ONE, nodSym(ir.ODOT, hit, keysym), nodnil())) fn = syslook("mapiternext") fn = substArgTypes(fn, th) - n.Right = mkcall1(fn, nil, nil, ir.Nod(ir.OADDR, hit, nil)) + n.SetRight(mkcall1(fn, nil, nil, ir.Nod(ir.OADDR, hit, nil))) key := nodSym(ir.ODOT, hit, keysym) key = ir.Nod(ir.ODEREF, key, nil) @@ -326,8 +326,8 @@ func walkrange(n *ir.Node) *ir.Node { elem := nodSym(ir.ODOT, hit, elemsym) elem = ir.Nod(ir.ODEREF, elem, nil) a := ir.Nod(ir.OAS2, nil, nil) - a.List.Set2(v1, v2) - a.Rlist.Set2(key, elem) + a.PtrList().Set2(v1, v2) + a.PtrRlist().Set2(key, elem) body = []*ir.Node{a} } @@ -335,7 +335,7 @@ func walkrange(n *ir.Node) *ir.Node { // order.stmt arranged for a copy of the channel variable. ha := a - n.Left = nil + n.SetLeft(nil) hv1 := temp(t.Elem()) hv1.SetTypecheck(1) @@ -344,12 +344,12 @@ func walkrange(n *ir.Node) *ir.Node { } hb := temp(types.Types[types.TBOOL]) - n.Left = ir.Nod(ir.ONE, hb, nodbool(false)) + n.SetLeft(ir.Nod(ir.ONE, hb, nodbool(false))) a := ir.Nod(ir.OAS2RECV, nil, nil) a.SetTypecheck(1) - a.List.Set2(hv1, hb) - a.Right = ir.Nod(ir.ORECV, ha, nil) - n.Left.Ninit.Set1(a) + a.PtrList().Set2(hv1, hb) + a.SetRight(ir.Nod(ir.ORECV, ha, nil)) + n.Left().PtrInit().Set1(a) if v1 == nil { body = nil } else { @@ -387,7 +387,7 @@ func walkrange(n *ir.Node) *ir.Node { init = append(init, ir.Nod(ir.OAS, hv1, nil)) // hv1 < len(ha) - n.Left = ir.Nod(ir.OLT, hv1, ir.Nod(ir.OLEN, ha, nil)) + n.SetLeft(ir.Nod(ir.OLT, hv1, ir.Nod(ir.OLEN, ha, nil))) if v1 != nil { // hv1t = hv1 @@ -401,19 +401,19 @@ func walkrange(n *ir.Node) *ir.Node { // if hv2 < utf8.RuneSelf nif := ir.Nod(ir.OIF, nil, nil) - nif.Left = ir.Nod(ir.OLT, hv2, nodintconst(utf8.RuneSelf)) + nif.SetLeft(ir.Nod(ir.OLT, hv2, nodintconst(utf8.RuneSelf))) // hv1++ - nif.Nbody.Set1(ir.Nod(ir.OAS, hv1, ir.Nod(ir.OADD, hv1, nodintconst(1)))) + nif.PtrBody().Set1(ir.Nod(ir.OAS, hv1, ir.Nod(ir.OADD, hv1, nodintconst(1)))) // } else { eif := ir.Nod(ir.OAS2, nil, nil) - nif.Rlist.Set1(eif) + nif.PtrRlist().Set1(eif) // hv2, hv1 = decoderune(ha, hv1) - eif.List.Set2(hv2, hv1) + eif.PtrList().Set2(hv2, hv1) fn := syslook("decoderune") - eif.Rlist.Set1(mkcall1(fn, fn.Type.Results(), nil, ha, hv1)) + eif.PtrRlist().Set1(mkcall1(fn, fn.Type().Results(), nil, ha, hv1)) body = append(body, nif) @@ -421,8 +421,8 @@ func walkrange(n *ir.Node) *ir.Node { if v2 != nil { // v1, v2 = hv1t, hv2 a := ir.Nod(ir.OAS2, nil, nil) - a.List.Set2(v1, v2) - a.Rlist.Set2(hv1t, hv2) + a.PtrList().Set2(v1, v2) + a.PtrRlist().Set2(hv1t, hv2) body = append(body, a) } else { // v1 = hv1t @@ -431,26 +431,26 @@ func walkrange(n *ir.Node) *ir.Node { } } - n.Op = translatedLoopOp + n.SetOp(translatedLoopOp) typecheckslice(init, ctxStmt) if ifGuard != nil { - ifGuard.Ninit.Append(init...) + ifGuard.PtrInit().Append(init...) ifGuard = typecheck(ifGuard, ctxStmt) } else { - n.Ninit.Append(init...) + n.PtrInit().Append(init...) } - typecheckslice(n.Left.Ninit.Slice(), ctxStmt) + typecheckslice(n.Left().Init().Slice(), ctxStmt) - n.Left = typecheck(n.Left, ctxExpr) - n.Left = defaultlit(n.Left, nil) - n.Right = typecheck(n.Right, ctxStmt) + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetLeft(defaultlit(n.Left(), nil)) + n.SetRight(typecheck(n.Right(), ctxStmt)) typecheckslice(body, ctxStmt) - n.Nbody.Prepend(body...) + n.PtrBody().Prepend(body...) if ifGuard != nil { - ifGuard.Nbody.Set1(n) + ifGuard.PtrBody().Set1(n) n = ifGuard } @@ -472,36 +472,36 @@ func isMapClear(n *ir.Node) bool { return false } - if n.Op != ir.ORANGE || n.Type.Etype != types.TMAP || n.List.Len() != 1 { + if n.Op() != ir.ORANGE || n.Type().Etype != types.TMAP || n.List().Len() != 1 { return false } - k := n.List.First() + k := n.List().First() if k == nil || ir.IsBlank(k) { return false } // Require k to be a new variable name. - if k.Name == nil || k.Name.Defn != n { + if k.Name() == nil || k.Name().Defn != n { return false } - if n.Nbody.Len() != 1 { + if n.Body().Len() != 1 { return false } - stmt := n.Nbody.First() // only stmt in body - if stmt == nil || stmt.Op != ir.ODELETE { + stmt := n.Body().First() // only stmt in body + if stmt == nil || stmt.Op() != ir.ODELETE { return false } - m := n.Right - if !samesafeexpr(stmt.List.First(), m) || !samesafeexpr(stmt.List.Second(), k) { + m := n.Right() + if !samesafeexpr(stmt.List().First(), m) || !samesafeexpr(stmt.List().Second(), k) { return false } // Keys where equality is not reflexive can not be deleted from maps. - if !isreflexive(m.Type.Key()) { + if !isreflexive(m.Type().Key()) { return false } @@ -510,7 +510,7 @@ func isMapClear(n *ir.Node) bool { // mapClear constructs a call to runtime.mapclear for the map m. func mapClear(m *ir.Node) *ir.Node { - t := m.Type + t := m.Type() // instantiate mapclear(typ *type, hmap map[any]any) fn := syslook("mapclear") @@ -543,21 +543,21 @@ func arrayClear(n, v1, v2, a *ir.Node) bool { return false } - if n.Nbody.Len() != 1 || n.Nbody.First() == nil { + if n.Body().Len() != 1 || n.Body().First() == nil { return false } - stmt := n.Nbody.First() // only stmt in body - if stmt.Op != ir.OAS || stmt.Left.Op != ir.OINDEX { + stmt := n.Body().First() // only stmt in body + if stmt.Op() != ir.OAS || stmt.Left().Op() != ir.OINDEX { return false } - if !samesafeexpr(stmt.Left.Left, a) || !samesafeexpr(stmt.Left.Right, v1) { + if !samesafeexpr(stmt.Left().Left(), a) || !samesafeexpr(stmt.Left().Right(), v1) { return false } - elemsize := n.Type.Elem().Width - if elemsize <= 0 || !isZero(stmt.Right) { + elemsize := n.Type().Elem().Width + if elemsize <= 0 || !isZero(stmt.Right()) { return false } @@ -568,10 +568,10 @@ func arrayClear(n, v1, v2, a *ir.Node) bool { // memclr{NoHeap,Has}Pointers(hp, hn) // i = len(a) - 1 // } - n.Op = ir.OIF + n.SetOp(ir.OIF) - n.Nbody.Set(nil) - n.Left = ir.Nod(ir.ONE, ir.Nod(ir.OLEN, a, nil), nodintconst(0)) + n.PtrBody().Set(nil) + n.SetLeft(ir.Nod(ir.ONE, ir.Nod(ir.OLEN, a, nil), nodintconst(0))) // hp = &a[0] hp := temp(types.Types[types.TUNSAFEPTR]) @@ -580,7 +580,7 @@ func arrayClear(n, v1, v2, a *ir.Node) bool { tmp.SetBounded(true) tmp = ir.Nod(ir.OADDR, tmp, nil) tmp = convnop(tmp, types.Types[types.TUNSAFEPTR]) - n.Nbody.Append(ir.Nod(ir.OAS, hp, tmp)) + n.PtrBody().Append(ir.Nod(ir.OAS, hp, tmp)) // hn = len(a) * sizeof(elem(a)) hn := temp(types.Types[types.TUINTPTR]) @@ -588,43 +588,43 @@ func arrayClear(n, v1, v2, a *ir.Node) bool { tmp = ir.Nod(ir.OLEN, a, nil) tmp = ir.Nod(ir.OMUL, tmp, nodintconst(elemsize)) tmp = conv(tmp, types.Types[types.TUINTPTR]) - n.Nbody.Append(ir.Nod(ir.OAS, hn, tmp)) + n.PtrBody().Append(ir.Nod(ir.OAS, hn, tmp)) var fn *ir.Node - if a.Type.Elem().HasPointers() { + if a.Type().Elem().HasPointers() { // memclrHasPointers(hp, hn) - Curfn.Func.SetWBPos(stmt.Pos) + Curfn.Func().SetWBPos(stmt.Pos()) fn = mkcall("memclrHasPointers", nil, nil, hp, hn) } else { // memclrNoHeapPointers(hp, hn) fn = mkcall("memclrNoHeapPointers", nil, nil, hp, hn) } - n.Nbody.Append(fn) + n.PtrBody().Append(fn) // i = len(a) - 1 v1 = ir.Nod(ir.OAS, v1, ir.Nod(ir.OSUB, ir.Nod(ir.OLEN, a, nil), nodintconst(1))) - n.Nbody.Append(v1) + n.PtrBody().Append(v1) - n.Left = typecheck(n.Left, ctxExpr) - n.Left = defaultlit(n.Left, nil) - typecheckslice(n.Nbody.Slice(), ctxStmt) + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetLeft(defaultlit(n.Left(), nil)) + typecheckslice(n.Body().Slice(), ctxStmt) n = walkstmt(n) return true } // addptr returns (*T)(uintptr(p) + n). func addptr(p *ir.Node, n int64) *ir.Node { - t := p.Type + t := p.Type() p = ir.Nod(ir.OCONVNOP, p, nil) - p.Type = types.Types[types.TUINTPTR] + p.SetType(types.Types[types.TUINTPTR]) p = ir.Nod(ir.OADD, p, nodintconst(n)) p = ir.Nod(ir.OCONVNOP, p, nil) - p.Type = t + p.SetType(t) return p } diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go index 34047bfefa..4559dd3a21 100644 --- a/src/cmd/compile/internal/gc/reflect.go +++ b/src/cmd/compile/internal/gc/reflect.go @@ -994,14 +994,14 @@ func typename(t *types.Type) *ir.Node { s := typenamesym(t) if s.Def == nil { n := ir.NewNameAt(src.NoXPos, s) - n.Type = types.Types[types.TUINT8] + n.SetType(types.Types[types.TUINT8]) n.SetClass(ir.PEXTERN) n.SetTypecheck(1) s.Def = ir.AsTypesNode(n) } n := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil) - n.Type = types.NewPtr(ir.AsNode(s.Def).Type) + n.SetType(types.NewPtr(ir.AsNode(s.Def).Type())) n.SetTypecheck(1) return n } @@ -1013,7 +1013,7 @@ func itabname(t, itype *types.Type) *ir.Node { s := itabpkg.Lookup(t.ShortString() + "," + itype.ShortString()) if s.Def == nil { n := NewName(s) - n.Type = types.Types[types.TUINT8] + n.SetType(types.Types[types.TUINT8]) n.SetClass(ir.PEXTERN) n.SetTypecheck(1) s.Def = ir.AsTypesNode(n) @@ -1021,7 +1021,7 @@ func itabname(t, itype *types.Type) *ir.Node { } n := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil) - n.Type = types.NewPtr(ir.AsNode(s.Def).Type) + n.SetType(types.NewPtr(ir.AsNode(s.Def).Type())) n.SetTypecheck(1) return n } @@ -1519,8 +1519,8 @@ func addsignat(t *types.Type) { func addsignats(dcls []*ir.Node) { // copy types from dcl list to signatset for _, n := range dcls { - if n.Op == ir.OTYPE { - addsignat(n.Type) + if n.Op() == ir.OTYPE { + addsignat(n.Type()) } } } @@ -1879,13 +1879,13 @@ func zeroaddr(size int64) *ir.Node { s := mappkg.Lookup("zero") if s.Def == nil { x := NewName(s) - x.Type = types.Types[types.TUINT8] + x.SetType(types.Types[types.TUINT8]) x.SetClass(ir.PEXTERN) x.SetTypecheck(1) s.Def = ir.AsTypesNode(x) } z := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil) - z.Type = types.NewPtr(types.Types[types.TUINT8]) + z.SetType(types.NewPtr(types.Types[types.TUINT8])) z.SetTypecheck(1) return z } diff --git a/src/cmd/compile/internal/gc/scc.go b/src/cmd/compile/internal/gc/scc.go index ddde18e505..880eff7595 100644 --- a/src/cmd/compile/internal/gc/scc.go +++ b/src/cmd/compile/internal/gc/scc.go @@ -56,7 +56,7 @@ func visitBottomUp(list []*ir.Node, analyze func(list []*ir.Node, recursive bool v.analyze = analyze v.nodeID = make(map[*ir.Node]uint32) for _, n := range list { - if n.Op == ir.ODCLFUNC && !n.Func.IsHiddenClosure() { + if n.Op() == ir.ODCLFUNC && !n.Func().IsHiddenClosure() { v.visit(n) } } @@ -75,46 +75,46 @@ func (v *bottomUpVisitor) visit(n *ir.Node) uint32 { min := v.visitgen v.stack = append(v.stack, n) - ir.InspectList(n.Nbody, func(n *ir.Node) bool { - switch n.Op { + ir.InspectList(n.Body(), func(n *ir.Node) bool { + switch n.Op() { case ir.ONAME: if n.Class() == ir.PFUNC { - if n != nil && n.Name.Defn != nil { - if m := v.visit(n.Name.Defn); m < min { + if n != nil && n.Name().Defn != nil { + if m := v.visit(n.Name().Defn); m < min { min = m } } } case ir.OMETHEXPR: fn := methodExprName(n) - if fn != nil && fn.Name.Defn != nil { - if m := v.visit(fn.Name.Defn); m < min { + if fn != nil && fn.Name().Defn != nil { + if m := v.visit(fn.Name().Defn); m < min { min = m } } case ir.ODOTMETH: fn := methodExprName(n) - if fn != nil && fn.Op == ir.ONAME && fn.Class() == ir.PFUNC && fn.Name.Defn != nil { - if m := v.visit(fn.Name.Defn); m < min { + if fn != nil && fn.Op() == ir.ONAME && fn.Class() == ir.PFUNC && fn.Name().Defn != nil { + if m := v.visit(fn.Name().Defn); m < min { min = m } } case ir.OCALLPART: fn := ir.AsNode(callpartMethod(n).Nname) - if fn != nil && fn.Op == ir.ONAME && fn.Class() == ir.PFUNC && fn.Name.Defn != nil { - if m := v.visit(fn.Name.Defn); m < min { + if fn != nil && fn.Op() == ir.ONAME && fn.Class() == ir.PFUNC && fn.Name().Defn != nil { + if m := v.visit(fn.Name().Defn); m < min { min = m } } case ir.OCLOSURE: - if m := v.visit(n.Func.Decl); m < min { + if m := v.visit(n.Func().Decl); m < min { min = m } } return true }) - if (min == id || min == id+1) && !n.Func.IsHiddenClosure() { + if (min == id || min == id+1) && !n.Func().IsHiddenClosure() { // This node is the root of a strongly connected component. // The original min passed to visitcodelist was v.nodeID[n]+1. diff --git a/src/cmd/compile/internal/gc/scope.go b/src/cmd/compile/internal/gc/scope.go index b5ebce04be..16e66dee6c 100644 --- a/src/cmd/compile/internal/gc/scope.go +++ b/src/cmd/compile/internal/gc/scope.go @@ -30,13 +30,13 @@ func findScope(marks []ir.Mark, pos src.XPos) ir.ScopeID { func assembleScopes(fnsym *obj.LSym, fn *ir.Node, dwarfVars []*dwarf.Var, varScopes []ir.ScopeID) []dwarf.Scope { // Initialize the DWARF scope tree based on lexical scopes. - dwarfScopes := make([]dwarf.Scope, 1+len(fn.Func.Parents)) - for i, parent := range fn.Func.Parents { + dwarfScopes := make([]dwarf.Scope, 1+len(fn.Func().Parents)) + for i, parent := range fn.Func().Parents { dwarfScopes[i+1].Parent = int32(parent) } scopeVariables(dwarfVars, varScopes, dwarfScopes) - scopePCs(fnsym, fn.Func.Marks, dwarfScopes) + scopePCs(fnsym, fn.Func().Marks, dwarfScopes) return compactScopes(dwarfScopes) } diff --git a/src/cmd/compile/internal/gc/select.go b/src/cmd/compile/internal/gc/select.go index ed7db0aaf7..73b808b815 100644 --- a/src/cmd/compile/internal/gc/select.go +++ b/src/cmd/compile/internal/gc/select.go @@ -14,36 +14,36 @@ import ( func typecheckselect(sel *ir.Node) { var def *ir.Node lno := setlineno(sel) - typecheckslice(sel.Ninit.Slice(), ctxStmt) - for _, ncase := range sel.List.Slice() { - if ncase.Op != ir.OCASE { + typecheckslice(sel.Init().Slice(), ctxStmt) + for _, ncase := range sel.List().Slice() { + if ncase.Op() != ir.OCASE { setlineno(ncase) - base.Fatalf("typecheckselect %v", ncase.Op) + base.Fatalf("typecheckselect %v", ncase.Op()) } - if ncase.List.Len() == 0 { + if ncase.List().Len() == 0 { // default if def != nil { - base.ErrorfAt(ncase.Pos, "multiple defaults in select (first at %v)", ir.Line(def)) + base.ErrorfAt(ncase.Pos(), "multiple defaults in select (first at %v)", ir.Line(def)) } else { def = ncase } - } else if ncase.List.Len() > 1 { - base.ErrorfAt(ncase.Pos, "select cases cannot be lists") + } else if ncase.List().Len() > 1 { + base.ErrorfAt(ncase.Pos(), "select cases cannot be lists") } else { - ncase.List.SetFirst(typecheck(ncase.List.First(), ctxStmt)) - n := ncase.List.First() - ncase.Left = n - ncase.List.Set(nil) - switch n.Op { + ncase.List().SetFirst(typecheck(ncase.List().First(), ctxStmt)) + n := ncase.List().First() + ncase.SetLeft(n) + ncase.PtrList().Set(nil) + switch n.Op() { default: - pos := n.Pos - if n.Op == ir.ONAME { + pos := n.Pos() + if n.Op() == ir.ONAME { // We don't have the right position for ONAME nodes (see #15459 and // others). Using ncase.Pos for now as it will provide the correct // line number (assuming the expression follows the "case" keyword // on the same line). This matches the approach before 1.10. - pos = ncase.Pos + pos = ncase.Pos() } base.ErrorfAt(pos, "select case must be receive, send or assign recv") @@ -51,41 +51,41 @@ func typecheckselect(sel *ir.Node) { // remove implicit conversions; the eventual assignment // will reintroduce them. case ir.OAS: - if (n.Right.Op == ir.OCONVNOP || n.Right.Op == ir.OCONVIFACE) && n.Right.Implicit() { - n.Right = n.Right.Left + if (n.Right().Op() == ir.OCONVNOP || n.Right().Op() == ir.OCONVIFACE) && n.Right().Implicit() { + n.SetRight(n.Right().Left()) } - if n.Right.Op != ir.ORECV { - base.ErrorfAt(n.Pos, "select assignment must have receive on right hand side") + if n.Right().Op() != ir.ORECV { + base.ErrorfAt(n.Pos(), "select assignment must have receive on right hand side") break } - n.Op = ir.OSELRECV + n.SetOp(ir.OSELRECV) // convert x, ok = <-c into OSELRECV2(x, <-c) with ntest=ok case ir.OAS2RECV: - if n.Right.Op != ir.ORECV { - base.ErrorfAt(n.Pos, "select assignment must have receive on right hand side") + if n.Right().Op() != ir.ORECV { + base.ErrorfAt(n.Pos(), "select assignment must have receive on right hand side") break } - n.Op = ir.OSELRECV2 - n.Left = n.List.First() - n.List.Set1(n.List.Second()) + n.SetOp(ir.OSELRECV2) + n.SetLeft(n.List().First()) + n.PtrList().Set1(n.List().Second()) // convert <-c into OSELRECV(N, <-c) case ir.ORECV: - n = ir.NodAt(n.Pos, ir.OSELRECV, nil, n) + n = ir.NodAt(n.Pos(), ir.OSELRECV, nil, n) n.SetTypecheck(1) - ncase.Left = n + ncase.SetLeft(n) case ir.OSEND: break } } - typecheckslice(ncase.Nbody.Slice(), ctxStmt) + typecheckslice(ncase.Body().Slice(), ctxStmt) } base.Pos = lno @@ -93,18 +93,18 @@ func typecheckselect(sel *ir.Node) { func walkselect(sel *ir.Node) { lno := setlineno(sel) - if sel.Nbody.Len() != 0 { + if sel.Body().Len() != 0 { base.Fatalf("double walkselect") } - init := sel.Ninit.Slice() - sel.Ninit.Set(nil) + init := sel.Init().Slice() + sel.PtrInit().Set(nil) - init = append(init, walkselectcases(&sel.List)...) - sel.List.Set(nil) + init = append(init, walkselectcases(sel.PtrList())...) + sel.PtrList().Set(nil) - sel.Nbody.Set(init) - walkstmtlist(sel.Nbody.Slice()) + sel.PtrBody().Set(init) + walkstmtlist(sel.Body().Slice()) base.Pos = lno } @@ -122,38 +122,38 @@ func walkselectcases(cases *ir.Nodes) []*ir.Node { if ncas == 1 { cas := cases.First() setlineno(cas) - l := cas.Ninit.Slice() - if cas.Left != nil { // not default: - n := cas.Left - l = append(l, n.Ninit.Slice()...) - n.Ninit.Set(nil) - switch n.Op { + l := cas.Init().Slice() + if cas.Left() != nil { // not default: + n := cas.Left() + l = append(l, n.Init().Slice()...) + n.PtrInit().Set(nil) + switch n.Op() { default: - base.Fatalf("select %v", n.Op) + base.Fatalf("select %v", n.Op()) case ir.OSEND: // already ok case ir.OSELRECV, ir.OSELRECV2: - if n.Op == ir.OSELRECV || n.List.Len() == 0 { - if n.Left == nil { - n = n.Right + if n.Op() == ir.OSELRECV || n.List().Len() == 0 { + if n.Left() == nil { + n = n.Right() } else { - n.Op = ir.OAS + n.SetOp(ir.OAS) } break } - if n.Left == nil { + if n.Left() == nil { ir.BlankNode = typecheck(ir.BlankNode, ctxExpr|ctxAssign) - n.Left = ir.BlankNode + n.SetLeft(ir.BlankNode) } - n.Op = ir.OAS2 - n.List.Prepend(n.Left) - n.Rlist.Set1(n.Right) - n.Right = nil - n.Left = nil + n.SetOp(ir.OAS2) + n.PtrList().Prepend(n.Left()) + n.PtrRlist().Set1(n.Right()) + n.SetRight(nil) + n.SetLeft(nil) n.SetTypecheck(0) n = typecheck(n, ctxStmt) } @@ -161,7 +161,7 @@ func walkselectcases(cases *ir.Nodes) []*ir.Node { l = append(l, n) } - l = append(l, cas.Nbody.Slice()...) + l = append(l, cas.Body().Slice()...) l = append(l, ir.Nod(ir.OBREAK, nil, nil)) return l } @@ -171,24 +171,24 @@ func walkselectcases(cases *ir.Nodes) []*ir.Node { var dflt *ir.Node for _, cas := range cases.Slice() { setlineno(cas) - n := cas.Left + n := cas.Left() if n == nil { dflt = cas continue } - switch n.Op { + switch n.Op() { case ir.OSEND: - n.Right = ir.Nod(ir.OADDR, n.Right, nil) - n.Right = typecheck(n.Right, ctxExpr) + n.SetRight(ir.Nod(ir.OADDR, n.Right(), nil)) + n.SetRight(typecheck(n.Right(), ctxExpr)) case ir.OSELRECV, ir.OSELRECV2: - if n.Op == ir.OSELRECV2 && n.List.Len() == 0 { - n.Op = ir.OSELRECV + if n.Op() == ir.OSELRECV2 && n.List().Len() == 0 { + n.SetOp(ir.OSELRECV) } - if n.Left != nil { - n.Left = ir.Nod(ir.OADDR, n.Left, nil) - n.Left = typecheck(n.Left, ctxExpr) + if n.Left() != nil { + n.SetLeft(ir.Nod(ir.OADDR, n.Left(), nil)) + n.SetLeft(typecheck(n.Left(), ctxExpr)) } } } @@ -200,43 +200,43 @@ func walkselectcases(cases *ir.Nodes) []*ir.Node { cas = cases.Second() } - n := cas.Left + n := cas.Left() setlineno(n) r := ir.Nod(ir.OIF, nil, nil) - r.Ninit.Set(cas.Ninit.Slice()) - switch n.Op { + r.PtrInit().Set(cas.Init().Slice()) + switch n.Op() { default: - base.Fatalf("select %v", n.Op) + base.Fatalf("select %v", n.Op()) case ir.OSEND: // if selectnbsend(c, v) { body } else { default body } - ch := n.Left - r.Left = mkcall1(chanfn("selectnbsend", 2, ch.Type), types.Types[types.TBOOL], &r.Ninit, ch, n.Right) + ch := n.Left() + r.SetLeft(mkcall1(chanfn("selectnbsend", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), ch, n.Right())) case ir.OSELRECV: // if selectnbrecv(&v, c) { body } else { default body } - ch := n.Right.Left - elem := n.Left + ch := n.Right().Left() + elem := n.Left() if elem == nil { elem = nodnil() } - r.Left = mkcall1(chanfn("selectnbrecv", 2, ch.Type), types.Types[types.TBOOL], &r.Ninit, elem, ch) + r.SetLeft(mkcall1(chanfn("selectnbrecv", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), elem, ch)) case ir.OSELRECV2: // if selectnbrecv2(&v, &received, c) { body } else { default body } - ch := n.Right.Left - elem := n.Left + ch := n.Right().Left() + elem := n.Left() if elem == nil { elem = nodnil() } - receivedp := ir.Nod(ir.OADDR, n.List.First(), nil) + receivedp := ir.Nod(ir.OADDR, n.List().First(), nil) receivedp = typecheck(receivedp, ctxExpr) - r.Left = mkcall1(chanfn("selectnbrecv2", 2, ch.Type), types.Types[types.TBOOL], &r.Ninit, elem, receivedp, ch) + r.SetLeft(mkcall1(chanfn("selectnbrecv2", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), elem, receivedp, ch)) } - r.Left = typecheck(r.Left, ctxExpr) - r.Nbody.Set(cas.Nbody.Slice()) - r.Rlist.Set(append(dflt.Ninit.Slice(), dflt.Nbody.Slice()...)) + r.SetLeft(typecheck(r.Left(), ctxExpr)) + r.PtrBody().Set(cas.Body().Slice()) + r.PtrRlist().Set(append(dflt.Init().Slice(), dflt.Body().Slice()...)) return []*ir.Node{r, ir.Nod(ir.OBREAK, nil, nil)} } @@ -270,29 +270,29 @@ func walkselectcases(cases *ir.Nodes) []*ir.Node { for _, cas := range cases.Slice() { setlineno(cas) - init = append(init, cas.Ninit.Slice()...) - cas.Ninit.Set(nil) + init = append(init, cas.Init().Slice()...) + cas.PtrInit().Set(nil) - n := cas.Left + n := cas.Left() if n == nil { // default: continue } var i int var c, elem *ir.Node - switch n.Op { + switch n.Op() { default: - base.Fatalf("select %v", n.Op) + base.Fatalf("select %v", n.Op()) case ir.OSEND: i = nsends nsends++ - c = n.Left - elem = n.Right + c = n.Left() + elem = n.Right() case ir.OSELRECV, ir.OSELRECV2: nrecvs++ i = ncas - nrecvs - c = n.Right.Left - elem = n.Left + c = n.Right().Left() + elem = n.Left() } casorder[i] = cas @@ -326,9 +326,9 @@ func walkselectcases(cases *ir.Nodes) []*ir.Node { chosen := temp(types.Types[types.TINT]) recvOK := temp(types.Types[types.TBOOL]) r = ir.Nod(ir.OAS2, nil, nil) - r.List.Set2(chosen, recvOK) + r.PtrList().Set2(chosen, recvOK) fn := syslook("selectgo") - r.Rlist.Set1(mkcall1(fn, fn.Type.Results(), nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), pc0, nodintconst(int64(nsends)), nodintconst(int64(nrecvs)), nodbool(dflt == nil))) + r.PtrRlist().Set1(mkcall1(fn, fn.Type().Results(), nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), pc0, nodintconst(int64(nsends)), nodintconst(int64(nrecvs)), nodbool(dflt == nil))) r = typecheck(r, ctxStmt) init = append(init, r) @@ -346,14 +346,14 @@ func walkselectcases(cases *ir.Nodes) []*ir.Node { r := ir.Nod(ir.OIF, cond, nil) - if n := cas.Left; n != nil && n.Op == ir.OSELRECV2 { - x := ir.Nod(ir.OAS, n.List.First(), recvOK) + if n := cas.Left(); n != nil && n.Op() == ir.OSELRECV2 { + x := ir.Nod(ir.OAS, n.List().First(), recvOK) x = typecheck(x, ctxStmt) - r.Nbody.Append(x) + r.PtrBody().Append(x) } - r.Nbody.AppendNodes(&cas.Nbody) - r.Nbody.Append(ir.Nod(ir.OBREAK, nil, nil)) + r.PtrBody().AppendNodes(cas.PtrBody()) + r.PtrBody().Append(ir.Nod(ir.OBREAK, nil, nil)) init = append(init, r) } diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go index 0ba7efb95e..c0f85a1e33 100644 --- a/src/cmd/compile/internal/gc/sinit.go +++ b/src/cmd/compile/internal/gc/sinit.go @@ -57,54 +57,54 @@ func (s *InitSchedule) tryStaticInit(n *ir.Node) bool { // replaced by multiple simple OAS assignments, and the other // OAS2* assignments mostly necessitate dynamic execution // anyway. - if n.Op != ir.OAS { + if n.Op() != ir.OAS { return false } - if ir.IsBlank(n.Left) && candiscard(n.Right) { + if ir.IsBlank(n.Left()) && candiscard(n.Right()) { return true } lno := setlineno(n) defer func() { base.Pos = lno }() - return s.staticassign(n.Left, n.Right) + return s.staticassign(n.Left(), n.Right()) } // like staticassign but we are copying an already // initialized value r. func (s *InitSchedule) staticcopy(l *ir.Node, r *ir.Node) bool { - if r.Op != ir.ONAME && r.Op != ir.OMETHEXPR { + if r.Op() != ir.ONAME && r.Op() != ir.OMETHEXPR { return false } if r.Class() == ir.PFUNC { pfuncsym(l, r) return true } - if r.Class() != ir.PEXTERN || r.Sym.Pkg != ir.LocalPkg { + if r.Class() != ir.PEXTERN || r.Sym().Pkg != ir.LocalPkg { return false } - if r.Name.Defn == nil { // probably zeroed but perhaps supplied externally and of unknown value + if r.Name().Defn == nil { // probably zeroed but perhaps supplied externally and of unknown value return false } - if r.Name.Defn.Op != ir.OAS { + if r.Name().Defn.Op() != ir.OAS { return false } - if r.Type.IsString() { // perhaps overwritten by cmd/link -X (#34675) + if r.Type().IsString() { // perhaps overwritten by cmd/link -X (#34675) return false } orig := r - r = r.Name.Defn.Right + r = r.Name().Defn.Right() - for r.Op == ir.OCONVNOP && !types.Identical(r.Type, l.Type) { - r = r.Left + for r.Op() == ir.OCONVNOP && !types.Identical(r.Type(), l.Type()) { + r = r.Left() } - switch r.Op { + switch r.Op() { case ir.ONAME, ir.OMETHEXPR: if s.staticcopy(l, r) { return true } // We may have skipped past one or more OCONVNOPs, so // use conv to ensure r is assignable to l (#13263). - s.append(ir.Nod(ir.OAS, l, conv(r, l.Type))) + s.append(ir.Nod(ir.OAS, l, conv(r, l.Type()))) return true case ir.ONIL: @@ -114,17 +114,17 @@ func (s *InitSchedule) staticcopy(l *ir.Node, r *ir.Node) bool { if isZero(r) { return true } - litsym(l, r, int(l.Type.Width)) + litsym(l, r, int(l.Type().Width)) return true case ir.OADDR: - if a := r.Left; a.Op == ir.ONAME { + if a := r.Left(); a.Op() == ir.ONAME { addrsym(l, a) return true } case ir.OPTRLIT: - switch r.Left.Op { + switch r.Left().Op() { case ir.OARRAYLIT, ir.OSLICELIT, ir.OSTRUCTLIT, ir.OMAPLIT: // copy pointer addrsym(l, s.inittemps[r]) @@ -134,7 +134,7 @@ func (s *InitSchedule) staticcopy(l *ir.Node, r *ir.Node) bool { case ir.OSLICELIT: // copy slice a := s.inittemps[r] - slicesym(l, a, r.Right.Int64Val()) + slicesym(l, a, r.Right().Int64Val()) return true case ir.OARRAYLIT, ir.OSTRUCTLIT: @@ -143,10 +143,10 @@ func (s *InitSchedule) staticcopy(l *ir.Node, r *ir.Node) bool { n := ir.Copy(l) for i := range p.E { e := &p.E[i] - n.Xoffset = l.Xoffset + e.Xoffset - n.Type = e.Expr.Type - if e.Expr.Op == ir.OLITERAL || e.Expr.Op == ir.ONIL { - litsym(n, e.Expr, int(n.Type.Width)) + n.SetOffset(l.Offset() + e.Xoffset) + n.SetType(e.Expr.Type()) + if e.Expr.Op() == ir.OLITERAL || e.Expr.Op() == ir.ONIL { + litsym(n, e.Expr, int(n.Type().Width)) continue } ll := ir.SepCopy(n) @@ -156,8 +156,8 @@ func (s *InitSchedule) staticcopy(l *ir.Node, r *ir.Node) bool { // Requires computation, but we're // copying someone else's computation. rr := ir.SepCopy(orig) - rr.Type = ll.Type - rr.Xoffset = rr.Xoffset + e.Xoffset + rr.SetType(ll.Type()) + rr.SetOffset(rr.Offset() + e.Xoffset) setlineno(rr) s.append(ir.Nod(ir.OAS, ll, rr)) } @@ -169,11 +169,11 @@ func (s *InitSchedule) staticcopy(l *ir.Node, r *ir.Node) bool { } func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool { - for r.Op == ir.OCONVNOP { - r = r.Left + for r.Op() == ir.OCONVNOP { + r = r.Left() } - switch r.Op { + switch r.Op() { case ir.ONAME, ir.OMETHEXPR: return s.staticcopy(l, r) @@ -184,36 +184,36 @@ func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool { if isZero(r) { return true } - litsym(l, r, int(l.Type.Width)) + litsym(l, r, int(l.Type().Width)) return true case ir.OADDR: - if nam := stataddr(r.Left); nam != nil { + if nam := stataddr(r.Left()); nam != nil { addrsym(l, nam) return true } fallthrough case ir.OPTRLIT: - switch r.Left.Op { + switch r.Left().Op() { case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT, ir.OSTRUCTLIT: // Init pointer. - a := staticname(r.Left.Type) + a := staticname(r.Left().Type()) s.inittemps[r] = a addrsym(l, a) // Init underlying literal. - if !s.staticassign(a, r.Left) { - s.append(ir.Nod(ir.OAS, a, r.Left)) + if !s.staticassign(a, r.Left()) { + s.append(ir.Nod(ir.OAS, a, r.Left())) } return true } //dump("not static ptrlit", r); case ir.OSTR2BYTES: - if l.Class() == ir.PEXTERN && r.Left.Op == ir.OLITERAL { - sval := r.Left.StringVal() + if l.Class() == ir.PEXTERN && r.Left().Op() == ir.OLITERAL { + sval := r.Left().StringVal() slicebytes(l, sval) return true } @@ -221,8 +221,8 @@ func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool { case ir.OSLICELIT: s.initplan(r) // Init slice. - bound := r.Right.Int64Val() - ta := types.NewArray(r.Type.Elem(), bound) + bound := r.Right().Int64Val() + ta := types.NewArray(r.Type().Elem(), bound) ta.SetNoalg(true) a := staticname(ta) s.inittemps[r] = a @@ -238,10 +238,10 @@ func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool { n := ir.Copy(l) for i := range p.E { e := &p.E[i] - n.Xoffset = l.Xoffset + e.Xoffset - n.Type = e.Expr.Type - if e.Expr.Op == ir.OLITERAL || e.Expr.Op == ir.ONIL { - litsym(n, e.Expr, int(n.Type.Width)) + n.SetOffset(l.Offset() + e.Xoffset) + n.SetType(e.Expr.Type()) + if e.Expr.Op() == ir.OLITERAL || e.Expr.Op() == ir.ONIL { + litsym(n, e.Expr, int(n.Type().Width)) continue } setlineno(e.Expr) @@ -259,11 +259,11 @@ func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool { case ir.OCLOSURE: if hasemptycvars(r) { if base.Debug.Closure > 0 { - base.WarnfAt(r.Pos, "closure converted to global") + base.WarnfAt(r.Pos(), "closure converted to global") } // Closures with no captured variables are globals, // so the assignment can be done at link time. - pfuncsym(l, r.Func.Nname) + pfuncsym(l, r.Func().Nname) return true } closuredebugruntimecheck(r) @@ -274,43 +274,43 @@ func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool { // Determine the underlying concrete type and value we are converting from. val := r - for val.Op == ir.OCONVIFACE { - val = val.Left + for val.Op() == ir.OCONVIFACE { + val = val.Left() } - if val.Type.IsInterface() { + if val.Type().IsInterface() { // val is an interface type. // If val is nil, we can statically initialize l; // both words are zero and so there no work to do, so report success. // If val is non-nil, we have no concrete type to record, // and we won't be able to statically initialize its value, so report failure. - return val.Op == ir.ONIL + return val.Op() == ir.ONIL } - markTypeUsedInInterface(val.Type, l.Sym.Linksym()) + markTypeUsedInInterface(val.Type(), l.Sym().Linksym()) var itab *ir.Node - if l.Type.IsEmptyInterface() { - itab = typename(val.Type) + if l.Type().IsEmptyInterface() { + itab = typename(val.Type()) } else { - itab = itabname(val.Type, l.Type) + itab = itabname(val.Type(), l.Type()) } // Create a copy of l to modify while we emit data. n := ir.Copy(l) // Emit itab, advance offset. - addrsym(n, itab.Left) // itab is an OADDR node - n.Xoffset = n.Xoffset + int64(Widthptr) + addrsym(n, itab.Left()) // itab is an OADDR node + n.SetOffset(n.Offset() + int64(Widthptr)) // Emit data. - if isdirectiface(val.Type) { - if val.Op == ir.ONIL { + if isdirectiface(val.Type()) { + if val.Op() == ir.ONIL { // Nil is zero, nothing to do. return true } // Copy val directly into n. - n.Type = val.Type + n.SetType(val.Type()) setlineno(val) a := ir.SepCopy(n) if !s.staticassign(a, val) { @@ -318,7 +318,7 @@ func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool { } } else { // Construct temp to hold val, write pointer to temp into n. - a := staticname(val.Type) + a := staticname(val.Type()) s.inittemps[val] = a if !s.staticassign(a, val) { s.append(ir.Nod(ir.OAS, a, val)) @@ -372,7 +372,7 @@ func staticname(t *types.Type) *ir.Node { n := NewName(lookup(fmt.Sprintf("%s%d", obj.StaticNamePref, statuniqgen))) statuniqgen++ addvar(n, t, ir.PEXTERN) - n.Sym.Linksym().Set(obj.AttrLocal, true) + n.Sym().Linksym().Set(obj.AttrLocal, true) return n } @@ -380,12 +380,12 @@ func staticname(t *types.Type) *ir.Node { func readonlystaticname(t *types.Type) *ir.Node { n := staticname(t) n.MarkReadonly() - n.Sym.Linksym().Set(obj.AttrContentAddressable, true) + n.Sym().Linksym().Set(obj.AttrContentAddressable, true) return n } func isSimpleName(n *ir.Node) bool { - return (n.Op == ir.ONAME || n.Op == ir.OMETHEXPR) && n.Class() != ir.PAUTOHEAP && n.Class() != ir.PEXTERN + return (n.Op() == ir.ONAME || n.Op() == ir.OMETHEXPR) && n.Class() != ir.PAUTOHEAP && n.Class() != ir.PEXTERN } func litas(l *ir.Node, r *ir.Node, init *ir.Nodes) { @@ -406,7 +406,7 @@ const ( // getdyn calculates the initGenType for n. // If top is false, getdyn is recursing. func getdyn(n *ir.Node, top bool) initGenType { - switch n.Op { + switch n.Op() { default: if isGoConst(n) { return initConst @@ -417,7 +417,7 @@ func getdyn(n *ir.Node, top bool) initGenType { if !top { return initDynamic } - if n.Right.Int64Val()/4 > int64(n.List.Len()) { + if n.Right().Int64Val()/4 > int64(n.List().Len()) { // <25% of entries have explicit values. // Very rough estimation, it takes 4 bytes of instructions // to initialize 1 byte of result. So don't use a static @@ -431,12 +431,12 @@ func getdyn(n *ir.Node, top bool) initGenType { } var mode initGenType - for _, n1 := range n.List.Slice() { - switch n1.Op { + for _, n1 := range n.List().Slice() { + switch n1.Op() { case ir.OKEY: - n1 = n1.Right + n1 = n1.Right() case ir.OSTRUCTKEY: - n1 = n1.Left + n1 = n1.Left() } mode |= getdyn(n1, false) if mode == initDynamic|initConst { @@ -448,13 +448,13 @@ func getdyn(n *ir.Node, top bool) initGenType { // isStaticCompositeLiteral reports whether n is a compile-time constant. func isStaticCompositeLiteral(n *ir.Node) bool { - switch n.Op { + switch n.Op() { case ir.OSLICELIT: return false case ir.OARRAYLIT: - for _, r := range n.List.Slice() { - if r.Op == ir.OKEY { - r = r.Right + for _, r := range n.List().Slice() { + if r.Op() == ir.OKEY { + r = r.Right() } if !isStaticCompositeLiteral(r) { return false @@ -462,11 +462,11 @@ func isStaticCompositeLiteral(n *ir.Node) bool { } return true case ir.OSTRUCTLIT: - for _, r := range n.List.Slice() { - if r.Op != ir.OSTRUCTKEY { + for _, r := range n.List().Slice() { + if r.Op() != ir.OSTRUCTKEY { base.Fatalf("isStaticCompositeLiteral: rhs not OSTRUCTKEY: %v", r) } - if !isStaticCompositeLiteral(r.Left) { + if !isStaticCompositeLiteral(r.Left()) { return false } } @@ -476,13 +476,13 @@ func isStaticCompositeLiteral(n *ir.Node) bool { case ir.OCONVIFACE: // See staticassign's OCONVIFACE case for comments. val := n - for val.Op == ir.OCONVIFACE { - val = val.Left + for val.Op() == ir.OCONVIFACE { + val = val.Left() } - if val.Type.IsInterface() { - return val.Op == ir.ONIL + if val.Type().IsInterface() { + return val.Op() == ir.ONIL } - if isdirectiface(val.Type) && val.Op == ir.ONIL { + if isdirectiface(val.Type()) && val.Op() == ir.ONIL { return true } return isStaticCompositeLiteral(val) @@ -512,16 +512,16 @@ const ( func fixedlit(ctxt initContext, kind initKind, n *ir.Node, var_ *ir.Node, init *ir.Nodes) { isBlank := var_ == ir.BlankNode var splitnode func(*ir.Node) (a *ir.Node, value *ir.Node) - switch n.Op { + switch n.Op() { case ir.OARRAYLIT, ir.OSLICELIT: var k int64 splitnode = func(r *ir.Node) (*ir.Node, *ir.Node) { - if r.Op == ir.OKEY { - k = indexconst(r.Left) + if r.Op() == ir.OKEY { + k = indexconst(r.Left()) if k < 0 { - base.Fatalf("fixedlit: invalid index %v", r.Left) + base.Fatalf("fixedlit: invalid index %v", r.Left()) } - r = r.Right + r = r.Right() } a := ir.Nod(ir.OINDEX, var_, nodintconst(k)) k++ @@ -532,26 +532,26 @@ func fixedlit(ctxt initContext, kind initKind, n *ir.Node, var_ *ir.Node, init * } case ir.OSTRUCTLIT: splitnode = func(r *ir.Node) (*ir.Node, *ir.Node) { - if r.Op != ir.OSTRUCTKEY { + if r.Op() != ir.OSTRUCTKEY { base.Fatalf("fixedlit: rhs not OSTRUCTKEY: %v", r) } - if r.Sym.IsBlank() || isBlank { - return ir.BlankNode, r.Left + if r.Sym().IsBlank() || isBlank { + return ir.BlankNode, r.Left() } setlineno(r) - return nodSym(ir.ODOT, var_, r.Sym), r.Left + return nodSym(ir.ODOT, var_, r.Sym()), r.Left() } default: - base.Fatalf("fixedlit bad op: %v", n.Op) + base.Fatalf("fixedlit bad op: %v", n.Op()) } - for _, r := range n.List.Slice() { + for _, r := range n.List().Slice() { a, value := splitnode(r) if a == ir.BlankNode && candiscard(value) { continue } - switch value.Op { + switch value.Op() { case ir.OSLICELIT: if (kind == initKindStatic && ctxt == inNonInitFunction) || (kind == initKindDynamic && ctxt == inInitFunction) { slicelit(ctxt, value, a, init) @@ -587,18 +587,18 @@ func fixedlit(ctxt initContext, kind initKind, n *ir.Node, var_ *ir.Node, init * } func isSmallSliceLit(n *ir.Node) bool { - if n.Op != ir.OSLICELIT { + if n.Op() != ir.OSLICELIT { return false } - r := n.Right + r := n.Right() - return smallintconst(r) && (n.Type.Elem().Width == 0 || r.Int64Val() <= smallArrayBytes/n.Type.Elem().Width) + return smallintconst(r) && (n.Type().Elem().Width == 0 || r.Int64Val() <= smallArrayBytes/n.Type().Elem().Width) } func slicelit(ctxt initContext, n *ir.Node, var_ *ir.Node, init *ir.Nodes) { // make an array type corresponding the number of elements we have - t := types.NewArray(n.Type.Elem(), n.Right.Int64Val()) + t := types.NewArray(n.Type().Elem(), n.Right().Int64Val()) dowidth(t) if ctxt == inNonInitFunction { @@ -658,7 +658,7 @@ func slicelit(ctxt initContext, n *ir.Node, var_ *ir.Node, init *ir.Nodes) { var a *ir.Node if x := prealloc[n]; x != nil { // temp allocated during order.go for dddarg - if !types.Identical(t, x.Type) { + if !types.Identical(t, x.Type()) { panic("dotdotdot base type does not match order's assigned type") } @@ -673,13 +673,13 @@ func slicelit(ctxt initContext, n *ir.Node, var_ *ir.Node, init *ir.Nodes) { } a = ir.Nod(ir.OADDR, x, nil) - } else if n.Esc == EscNone { + } else if n.Esc() == EscNone { a = temp(t) if vstat == nil { a = ir.Nod(ir.OAS, temp(t), nil) a = typecheck(a, ctxStmt) init.Append(a) // zero new temp - a = a.Left + a = a.Left() } else { init.Append(ir.Nod(ir.OVARDEF, a, nil)) } @@ -687,7 +687,7 @@ func slicelit(ctxt initContext, n *ir.Node, var_ *ir.Node, init *ir.Nodes) { a = ir.Nod(ir.OADDR, a, nil) } else { a = ir.Nod(ir.ONEW, nil, nil) - a.List.Set1(typenod(t)) + a.PtrList().Set1(typenod(t)) } a = ir.Nod(ir.OAS, vauto, a) @@ -707,13 +707,13 @@ func slicelit(ctxt initContext, n *ir.Node, var_ *ir.Node, init *ir.Nodes) { // put dynamics into array (5) var index int64 - for _, value := range n.List.Slice() { - if value.Op == ir.OKEY { - index = indexconst(value.Left) + for _, value := range n.List().Slice() { + if value.Op() == ir.OKEY { + index = indexconst(value.Left()) if index < 0 { - base.Fatalf("slicelit: invalid index %v", value.Left) + base.Fatalf("slicelit: invalid index %v", value.Left()) } - value = value.Right + value = value.Right() } a := ir.Nod(ir.OINDEX, vauto, nodintconst(index)) a.SetBounded(true) @@ -721,7 +721,7 @@ func slicelit(ctxt initContext, n *ir.Node, var_ *ir.Node, init *ir.Nodes) { // TODO need to check bounds? - switch value.Op { + switch value.Op() { case ir.OSLICELIT: break @@ -762,16 +762,16 @@ func slicelit(ctxt initContext, n *ir.Node, var_ *ir.Node, init *ir.Nodes) { func maplit(n *ir.Node, m *ir.Node, init *ir.Nodes) { // make the map var a := ir.Nod(ir.OMAKE, nil, nil) - a.Esc = n.Esc - a.List.Set2(typenod(n.Type), nodintconst(int64(n.List.Len()))) + a.SetEsc(n.Esc()) + a.PtrList().Set2(typenod(n.Type()), nodintconst(int64(n.List().Len()))) litas(m, a, init) - entries := n.List.Slice() + entries := n.List().Slice() // The order pass already removed any dynamic (runtime-computed) entries. // All remaining entries are static. Double-check that. for _, r := range entries { - if !isStaticCompositeLiteral(r.Left) || !isStaticCompositeLiteral(r.Right) { + if !isStaticCompositeLiteral(r.Left()) || !isStaticCompositeLiteral(r.Right()) { base.Fatalf("maplit: entry is not a literal: %v", r) } } @@ -780,8 +780,8 @@ func maplit(n *ir.Node, m *ir.Node, init *ir.Nodes) { // For a large number of entries, put them in an array and loop. // build types [count]Tindex and [count]Tvalue - tk := types.NewArray(n.Type.Key(), int64(len(entries))) - te := types.NewArray(n.Type.Elem(), int64(len(entries))) + tk := types.NewArray(n.Type().Key(), int64(len(entries))) + te := types.NewArray(n.Type().Elem(), int64(len(entries))) tk.SetNoalg(true) te.SetNoalg(true) @@ -796,8 +796,8 @@ func maplit(n *ir.Node, m *ir.Node, init *ir.Nodes) { datak := ir.Nod(ir.OARRAYLIT, nil, nil) datae := ir.Nod(ir.OARRAYLIT, nil, nil) for _, r := range entries { - datak.List.Append(r.Left) - datae.List.Append(r.Right) + datak.PtrList().Append(r.Left()) + datae.PtrList().Append(r.Right()) } fixedlit(inInitFunction, initKindStatic, datak, vstatk, init) fixedlit(inInitFunction, initKindStatic, datae, vstate, init) @@ -820,8 +820,8 @@ func maplit(n *ir.Node, m *ir.Node, init *ir.Nodes) { body := ir.Nod(ir.OAS, lhs, rhs) loop := ir.Nod(ir.OFOR, cond, incr) - loop.Nbody.Set1(body) - loop.Ninit.Set1(zero) + loop.PtrBody().Set1(body) + loop.PtrInit().Set1(zero) loop = typecheck(loop, ctxStmt) loop = walkstmt(loop) @@ -833,11 +833,11 @@ func maplit(n *ir.Node, m *ir.Node, init *ir.Nodes) { // Build list of var[c] = expr. // Use temporaries so that mapassign1 can have addressable key, elem. // TODO(josharian): avoid map key temporaries for mapfast_* assignments with literal keys. - tmpkey := temp(m.Type.Key()) - tmpelem := temp(m.Type.Elem()) + tmpkey := temp(m.Type().Key()) + tmpelem := temp(m.Type().Elem()) for _, r := range entries { - index, elem := r.Left, r.Right + index, elem := r.Left(), r.Right() setlineno(index) a := ir.Nod(ir.OAS, tmpkey, index) @@ -867,10 +867,10 @@ func maplit(n *ir.Node, m *ir.Node, init *ir.Nodes) { } func anylit(n *ir.Node, var_ *ir.Node, init *ir.Nodes) { - t := n.Type - switch n.Op { + t := n.Type() + switch n.Op() { default: - base.Fatalf("anylit: not lit, op=%v node=%v", n.Op, n) + base.Fatalf("anylit: not lit, op=%v node=%v", n.Op(), n) case ir.ONAME, ir.OMETHEXPR: a := ir.Nod(ir.OAS, var_, n) @@ -883,16 +883,16 @@ func anylit(n *ir.Node, var_ *ir.Node, init *ir.Nodes) { } var r *ir.Node - if n.Right != nil { + if n.Right() != nil { // n.Right is stack temporary used as backing store. - init.Append(ir.Nod(ir.OAS, n.Right, nil)) // zero backing store, just in case (#18410) - r = ir.Nod(ir.OADDR, n.Right, nil) + init.Append(ir.Nod(ir.OAS, n.Right(), nil)) // zero backing store, just in case (#18410) + r = ir.Nod(ir.OADDR, n.Right(), nil) r = typecheck(r, ctxExpr) } else { r = ir.Nod(ir.ONEW, nil, nil) r.SetTypecheck(1) - r.Type = t - r.Esc = n.Esc + r.SetType(t) + r.SetEsc(n.Esc()) } r = walkexpr(r, init) @@ -903,19 +903,19 @@ func anylit(n *ir.Node, var_ *ir.Node, init *ir.Nodes) { var_ = ir.Nod(ir.ODEREF, var_, nil) var_ = typecheck(var_, ctxExpr|ctxAssign) - anylit(n.Left, var_, init) + anylit(n.Left(), var_, init) case ir.OSTRUCTLIT, ir.OARRAYLIT: if !t.IsStruct() && !t.IsArray() { base.Fatalf("anylit: not struct/array") } - if isSimpleName(var_) && n.List.Len() > 4 { + if isSimpleName(var_) && n.List().Len() > 4 { // lay out static data vstat := readonlystaticname(t) ctxt := inInitFunction - if n.Op == ir.OARRAYLIT { + if n.Op() == ir.OARRAYLIT { ctxt = inNonInitFunction } fixedlit(ctxt, initKindStatic, n, vstat, init) @@ -933,13 +933,13 @@ func anylit(n *ir.Node, var_ *ir.Node, init *ir.Nodes) { } var components int64 - if n.Op == ir.OARRAYLIT { + if n.Op() == ir.OARRAYLIT { components = t.NumElem() } else { components = int64(t.NumFields()) } // initialization of an array or struct with unspecified components (missing fields or arrays) - if isSimpleName(var_) || int64(n.List.Len()) < components { + if isSimpleName(var_) || int64(n.List().Len()) < components { a := ir.Nod(ir.OAS, var_, nil) a = typecheck(a, ctxStmt) a = walkexpr(a, init) @@ -960,38 +960,38 @@ func anylit(n *ir.Node, var_ *ir.Node, init *ir.Nodes) { } func oaslit(n *ir.Node, init *ir.Nodes) bool { - if n.Left == nil || n.Right == nil { + if n.Left() == nil || n.Right() == nil { // not a special composite literal assignment return false } - if n.Left.Type == nil || n.Right.Type == nil { + if n.Left().Type() == nil || n.Right().Type() == nil { // not a special composite literal assignment return false } - if !isSimpleName(n.Left) { + if !isSimpleName(n.Left()) { // not a special composite literal assignment return false } - if !types.Identical(n.Left.Type, n.Right.Type) { + if !types.Identical(n.Left().Type(), n.Right().Type()) { // not a special composite literal assignment return false } - switch n.Right.Op { + switch n.Right().Op() { default: // not a special composite literal assignment return false case ir.OSTRUCTLIT, ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT: - if vmatch1(n.Left, n.Right) { + if vmatch1(n.Left(), n.Right()) { // not a special composite literal assignment return false } - anylit(n.Right, n.Left, init) + anylit(n.Right(), n.Left(), init) } - n.Op = ir.OEMPTY - n.Right = nil + n.SetOp(ir.OEMPTY) + n.SetRight(nil) return true } @@ -1008,38 +1008,38 @@ func stataddr(n *ir.Node) *ir.Node { return nil } - switch n.Op { + switch n.Op() { case ir.ONAME, ir.OMETHEXPR: return ir.SepCopy(n) case ir.ODOT: - nam := stataddr(n.Left) + nam := stataddr(n.Left()) if nam == nil { break } - nam.Xoffset = nam.Xoffset + n.Xoffset - nam.Type = n.Type + nam.SetOffset(nam.Offset() + n.Offset()) + nam.SetType(n.Type()) return nam case ir.OINDEX: - if n.Left.Type.IsSlice() { + if n.Left().Type().IsSlice() { break } - nam := stataddr(n.Left) + nam := stataddr(n.Left()) if nam == nil { break } - l := getlit(n.Right) + l := getlit(n.Right()) if l < 0 { break } // Check for overflow. - if n.Type.Width != 0 && thearch.MAXWIDTH/n.Type.Width <= int64(l) { + if n.Type().Width != 0 && thearch.MAXWIDTH/n.Type().Width <= int64(l) { break } - nam.Xoffset = nam.Xoffset + int64(l)*n.Type.Width - nam.Type = n.Type + nam.SetOffset(nam.Offset() + int64(l)*n.Type().Width) + nam.SetType(n.Type()) return nam } @@ -1052,41 +1052,41 @@ func (s *InitSchedule) initplan(n *ir.Node) { } p := new(InitPlan) s.initplans[n] = p - switch n.Op { + switch n.Op() { default: base.Fatalf("initplan") case ir.OARRAYLIT, ir.OSLICELIT: var k int64 - for _, a := range n.List.Slice() { - if a.Op == ir.OKEY { - k = indexconst(a.Left) + for _, a := range n.List().Slice() { + if a.Op() == ir.OKEY { + k = indexconst(a.Left()) if k < 0 { - base.Fatalf("initplan arraylit: invalid index %v", a.Left) + base.Fatalf("initplan arraylit: invalid index %v", a.Left()) } - a = a.Right + a = a.Right() } - s.addvalue(p, k*n.Type.Elem().Width, a) + s.addvalue(p, k*n.Type().Elem().Width, a) k++ } case ir.OSTRUCTLIT: - for _, a := range n.List.Slice() { - if a.Op != ir.OSTRUCTKEY { + for _, a := range n.List().Slice() { + if a.Op() != ir.OSTRUCTKEY { base.Fatalf("initplan structlit") } - if a.Sym.IsBlank() { + if a.Sym().IsBlank() { continue } - s.addvalue(p, a.Xoffset, a.Left) + s.addvalue(p, a.Offset(), a.Left()) } case ir.OMAPLIT: - for _, a := range n.List.Slice() { - if a.Op != ir.OKEY { + for _, a := range n.List().Slice() { + if a.Op() != ir.OKEY { base.Fatalf("initplan maplit") } - s.addvalue(p, -1, a.Right) + s.addvalue(p, -1, a.Right()) } } } @@ -1114,7 +1114,7 @@ func (s *InitSchedule) addvalue(p *InitPlan, xoffset int64, n *ir.Node) { } func isZero(n *ir.Node) bool { - switch n.Op { + switch n.Op() { case ir.ONIL: return true @@ -1129,9 +1129,9 @@ func isZero(n *ir.Node) bool { } case ir.OARRAYLIT: - for _, n1 := range n.List.Slice() { - if n1.Op == ir.OKEY { - n1 = n1.Right + for _, n1 := range n.List().Slice() { + if n1.Op() == ir.OKEY { + n1 = n1.Right() } if !isZero(n1) { return false @@ -1140,8 +1140,8 @@ func isZero(n *ir.Node) bool { return true case ir.OSTRUCTLIT: - for _, n1 := range n.List.Slice() { - if !isZero(n1.Left) { + for _, n1 := range n.List().Slice() { + if !isZero(n1.Left()) { return false } } @@ -1152,25 +1152,25 @@ func isZero(n *ir.Node) bool { } func isvaluelit(n *ir.Node) bool { - return n.Op == ir.OARRAYLIT || n.Op == ir.OSTRUCTLIT + return n.Op() == ir.OARRAYLIT || n.Op() == ir.OSTRUCTLIT } func genAsStatic(as *ir.Node) { - if as.Left.Type == nil { + if as.Left().Type() == nil { base.Fatalf("genAsStatic as.Left not typechecked") } - nam := stataddr(as.Left) - if nam == nil || (nam.Class() != ir.PEXTERN && as.Left != ir.BlankNode) { - base.Fatalf("genAsStatic: lhs %v", as.Left) + nam := stataddr(as.Left()) + if nam == nil || (nam.Class() != ir.PEXTERN && as.Left() != ir.BlankNode) { + base.Fatalf("genAsStatic: lhs %v", as.Left()) } switch { - case as.Right.Op == ir.OLITERAL: - litsym(nam, as.Right, int(as.Right.Type.Width)) - case (as.Right.Op == ir.ONAME || as.Right.Op == ir.OMETHEXPR) && as.Right.Class() == ir.PFUNC: - pfuncsym(nam, as.Right) + case as.Right().Op() == ir.OLITERAL: + litsym(nam, as.Right(), int(as.Right().Type().Width)) + case (as.Right().Op() == ir.ONAME || as.Right().Op() == ir.OMETHEXPR) && as.Right().Class() == ir.PFUNC: + pfuncsym(nam, as.Right()) default: - base.Fatalf("genAsStatic: rhs %v", as.Right) + base.Fatalf("genAsStatic: rhs %v", as.Right()) } } diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index 5cee3fab85..018b94d9d8 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -187,8 +187,8 @@ func initssaconfig() { // considered as the 0th parameter. This does not include the receiver of an // interface call. func getParam(n *ir.Node, i int) *types.Field { - t := n.Left.Type - if n.Op == ir.OCALLMETH { + t := n.Left().Type() + if n.Op() == ir.OCALLMETH { if i == 0 { return t.Recv() } @@ -242,8 +242,8 @@ func dvarint(x *obj.LSym, off int, v int64) int { // - Size of the argument // - Offset of where argument should be placed in the args frame when making call func (s *state) emitOpenDeferInfo() { - x := base.Ctxt.Lookup(s.curfn.Func.LSym.Name + ".opendefer") - s.curfn.Func.LSym.Func().OpenCodedDeferInfo = x + x := base.Ctxt.Lookup(s.curfn.Func().LSym.Name + ".opendefer") + s.curfn.Func().LSym.Func().OpenCodedDeferInfo = x off := 0 // Compute maxargsize (max size of arguments for all defers) @@ -251,20 +251,20 @@ func (s *state) emitOpenDeferInfo() { var maxargsize int64 for i := len(s.openDefers) - 1; i >= 0; i-- { r := s.openDefers[i] - argsize := r.n.Left.Type.ArgWidth() + argsize := r.n.Left().Type().ArgWidth() if argsize > maxargsize { maxargsize = argsize } } off = dvarint(x, off, maxargsize) - off = dvarint(x, off, -s.deferBitsTemp.Xoffset) + off = dvarint(x, off, -s.deferBitsTemp.Offset()) off = dvarint(x, off, int64(len(s.openDefers))) // Write in reverse-order, for ease of running in that order at runtime for i := len(s.openDefers) - 1; i >= 0; i-- { r := s.openDefers[i] - off = dvarint(x, off, r.n.Left.Type.ArgWidth()) - off = dvarint(x, off, -r.closureNode.Xoffset) + off = dvarint(x, off, r.n.Left().Type().ArgWidth()) + off = dvarint(x, off, -r.closureNode.Offset()) numArgs := len(r.argNodes) if r.rcvrNode != nil { // If there's an interface receiver, treat/place it as the first @@ -274,13 +274,13 @@ func (s *state) emitOpenDeferInfo() { } off = dvarint(x, off, int64(numArgs)) if r.rcvrNode != nil { - off = dvarint(x, off, -r.rcvrNode.Xoffset) + off = dvarint(x, off, -r.rcvrNode.Offset()) off = dvarint(x, off, s.config.PtrSize) off = dvarint(x, off, 0) } for j, arg := range r.argNodes { f := getParam(r.n, j) - off = dvarint(x, off, -arg.Xoffset) + off = dvarint(x, off, -arg.Offset()) off = dvarint(x, off, f.Type.Size()) off = dvarint(x, off, f.Offset) } @@ -298,9 +298,9 @@ func buildssa(fn *ir.Node, worker int) *ssa.Func { var astBuf *bytes.Buffer if printssa { astBuf = &bytes.Buffer{} - ir.FDumpList(astBuf, "buildssa-enter", fn.Func.Enter) - ir.FDumpList(astBuf, "buildssa-body", fn.Nbody) - ir.FDumpList(astBuf, "buildssa-exit", fn.Func.Exit) + ir.FDumpList(astBuf, "buildssa-enter", fn.Func().Enter) + ir.FDumpList(astBuf, "buildssa-body", fn.Body()) + ir.FDumpList(astBuf, "buildssa-exit", fn.Func().Exit) if ssaDumpStdout { fmt.Println("generating SSA for", name) fmt.Print(astBuf.String()) @@ -308,11 +308,11 @@ func buildssa(fn *ir.Node, worker int) *ssa.Func { } var s state - s.pushLine(fn.Pos) + s.pushLine(fn.Pos()) defer s.popLine() - s.hasdefer = fn.Func.HasDefer() - if fn.Func.Pragma&ir.CgoUnsafeArgs != 0 { + s.hasdefer = fn.Func().HasDefer() + if fn.Func().Pragma&ir.CgoUnsafeArgs != 0 { s.cgoUnsafeArgs = true } @@ -324,14 +324,14 @@ func buildssa(fn *ir.Node, worker int) *ssa.Func { s.f = ssa.NewFunc(&fe) s.config = ssaConfig - s.f.Type = fn.Type + s.f.Type = fn.Type() s.f.Config = ssaConfig s.f.Cache = &ssaCaches[worker] s.f.Cache.Reset() s.f.Name = name s.f.DebugTest = s.f.DebugHashMatch("GOSSAHASH") s.f.PrintOrHtmlSSA = printssa - if fn.Func.Pragma&ir.Nosplit != 0 { + if fn.Func().Pragma&ir.Nosplit != 0 { s.f.NoSplit = true } s.panics = map[funcLine]*ssa.Block{} @@ -339,7 +339,7 @@ func buildssa(fn *ir.Node, worker int) *ssa.Func { // Allocate starting block s.f.Entry = s.f.NewBlock(ssa.BlockPlain) - s.f.Entry.Pos = fn.Pos + s.f.Entry.Pos = fn.Pos() if printssa { ssaDF := ssaDumpFile @@ -360,7 +360,7 @@ func buildssa(fn *ir.Node, worker int) *ssa.Func { s.fwdVars = map[*ir.Node]*ssa.Value{} s.startmem = s.entryNewValue0(ssa.OpInitMem, types.TypeMem) - s.hasOpenDefers = base.Flag.N == 0 && s.hasdefer && !s.curfn.Func.OpenCodedDeferDisallowed() + s.hasOpenDefers = base.Flag.N == 0 && s.hasdefer && !s.curfn.Func().OpenCodedDeferDisallowed() switch { case s.hasOpenDefers && (base.Ctxt.Flag_shared || base.Ctxt.Flag_dynlink) && thearch.LinkArch.Name == "386": // Don't support open-coded defers for 386 ONLY when using shared @@ -369,7 +369,7 @@ func buildssa(fn *ir.Node, worker int) *ssa.Func { // that we don't track correctly. s.hasOpenDefers = false } - if s.hasOpenDefers && s.curfn.Func.Exit.Len() > 0 { + if s.hasOpenDefers && s.curfn.Func().Exit.Len() > 0 { // Skip doing open defers if there is any extra exit code (likely // copying heap-allocated return values or race detection), since // we will not generate that code in the case of the extra @@ -377,7 +377,7 @@ func buildssa(fn *ir.Node, worker int) *ssa.Func { s.hasOpenDefers = false } if s.hasOpenDefers && - s.curfn.Func.NumReturns*s.curfn.Func.NumDefers > 15 { + s.curfn.Func().NumReturns*s.curfn.Func().NumDefers > 15 { // Since we are generating defer calls at every exit for // open-coded defers, skip doing open-coded defers if there are // too many returns (especially if there are multiple defers). @@ -414,14 +414,14 @@ func buildssa(fn *ir.Node, worker int) *ssa.Func { s.decladdrs = map[*ir.Node]*ssa.Value{} var args []ssa.Param var results []ssa.Param - for _, n := range fn.Func.Dcl { + for _, n := range fn.Func().Dcl { switch n.Class() { case ir.PPARAM: - s.decladdrs[n] = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(n.Type), n, s.sp, s.startmem) - args = append(args, ssa.Param{Type: n.Type, Offset: int32(n.Xoffset)}) + s.decladdrs[n] = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(n.Type()), n, s.sp, s.startmem) + args = append(args, ssa.Param{Type: n.Type(), Offset: int32(n.Offset())}) case ir.PPARAMOUT: - s.decladdrs[n] = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(n.Type), n, s.sp, s.startmem) - results = append(results, ssa.Param{Type: n.Type, Offset: int32(n.Xoffset)}) + s.decladdrs[n] = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(n.Type()), n, s.sp, s.startmem) + results = append(results, ssa.Param{Type: n.Type(), Offset: int32(n.Offset())}) if s.canSSA(n) { // Save ssa-able PPARAMOUT variables so we can // store them back to the stack at the end of @@ -441,21 +441,21 @@ func buildssa(fn *ir.Node, worker int) *ssa.Func { } // Populate SSAable arguments. - for _, n := range fn.Func.Dcl { + for _, n := range fn.Func().Dcl { if n.Class() == ir.PPARAM && s.canSSA(n) { - v := s.newValue0A(ssa.OpArg, n.Type, n) + v := s.newValue0A(ssa.OpArg, n.Type(), n) s.vars[n] = v s.addNamedValue(n, v) // This helps with debugging information, not needed for compilation itself. } } // Convert the AST-based IR to the SSA-based IR - s.stmtList(fn.Func.Enter) - s.stmtList(fn.Nbody) + s.stmtList(fn.Func().Enter) + s.stmtList(fn.Body()) // fallthrough to exit if s.curBlock != nil { - s.pushLine(fn.Func.Endlineno) + s.pushLine(fn.Func().Endlineno) s.exit() s.popLine() } @@ -480,8 +480,8 @@ func buildssa(fn *ir.Node, worker int) *ssa.Func { func dumpSourcesColumn(writer *ssa.HTMLWriter, fn *ir.Node) { // Read sources of target function fn. - fname := base.Ctxt.PosTable.Pos(fn.Pos).Filename() - targetFn, err := readFuncLines(fname, fn.Pos.Line(), fn.Func.Endlineno.Line()) + fname := base.Ctxt.PosTable.Pos(fn.Pos()).Filename() + targetFn, err := readFuncLines(fname, fn.Pos().Line(), fn.Func().Endlineno.Line()) if err != nil { writer.Logf("cannot read sources for function %v: %v", fn, err) } @@ -490,14 +490,14 @@ func dumpSourcesColumn(writer *ssa.HTMLWriter, fn *ir.Node) { var inlFns []*ssa.FuncLines for _, fi := range ssaDumpInlined { var elno src.XPos - if fi.Name.Defn == nil { + if fi.Name().Defn == nil { // Endlineno is filled from exported data. - elno = fi.Func.Endlineno + elno = fi.Func().Endlineno } else { - elno = fi.Name.Defn.Func.Endlineno + elno = fi.Name().Defn.Func().Endlineno } - fname := base.Ctxt.PosTable.Pos(fi.Pos).Filename() - fnLines, err := readFuncLines(fname, fi.Pos.Line(), elno.Line()) + fname := base.Ctxt.PosTable.Pos(fi.Pos()).Filename() + fnLines, err := readFuncLines(fname, fi.Pos().Line(), elno.Line()) if err != nil { writer.Logf("cannot read sources for inlined function %v: %v", fi, err) continue @@ -974,7 +974,7 @@ func (s *state) newValueOrSfCall2(op ssa.Op, t *types.Type, arg0, arg1 *ssa.Valu } func (s *state) instrument(t *types.Type, addr *ssa.Value, wr bool) { - if !s.curfn.Func.InstrumentBody() { + if !s.curfn.Func().InstrumentBody() { return } @@ -1060,23 +1060,23 @@ func (s *state) stmtList(l ir.Nodes) { // stmt converts the statement n to SSA and adds it to s. func (s *state) stmt(n *ir.Node) { - if !(n.Op == ir.OVARKILL || n.Op == ir.OVARLIVE || n.Op == ir.OVARDEF) { + if !(n.Op() == ir.OVARKILL || n.Op() == ir.OVARLIVE || n.Op() == ir.OVARDEF) { // OVARKILL, OVARLIVE, and OVARDEF are invisible to the programmer, so we don't use their line numbers to avoid confusion in debugging. - s.pushLine(n.Pos) + s.pushLine(n.Pos()) defer s.popLine() } // If s.curBlock is nil, and n isn't a label (which might have an associated goto somewhere), // then this code is dead. Stop here. - if s.curBlock == nil && n.Op != ir.OLABEL { + if s.curBlock == nil && n.Op() != ir.OLABEL { return } - s.stmtList(n.Ninit) - switch n.Op { + s.stmtList(n.Init()) + switch n.Op() { case ir.OBLOCK: - s.stmtList(n.List) + s.stmtList(n.List()) // No-ops case ir.OEMPTY, ir.ODCLCONST, ir.ODCLTYPE, ir.OFALL: @@ -1091,9 +1091,9 @@ func (s *state) stmt(n *ir.Node) { case ir.OCALLMETH, ir.OCALLINTER: s.callResult(n, callNormal) - if n.Op == ir.OCALLFUNC && n.Left.Op == ir.ONAME && n.Left.Class() == ir.PFUNC { - if fn := n.Left.Sym.Name; base.Flag.CompilingRuntime && fn == "throw" || - n.Left.Sym.Pkg == Runtimepkg && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap") { + if n.Op() == ir.OCALLFUNC && n.Left().Op() == ir.ONAME && n.Left().Class() == ir.PFUNC { + if fn := n.Left().Sym().Name; base.Flag.CompilingRuntime && fn == "throw" || + n.Left().Sym().Pkg == Runtimepkg && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap") { m := s.mem() b := s.endBlock() b.Kind = ssa.BlockExit @@ -1108,29 +1108,29 @@ func (s *state) stmt(n *ir.Node) { var defertype string if s.hasOpenDefers { defertype = "open-coded" - } else if n.Esc == EscNever { + } else if n.Esc() == EscNever { defertype = "stack-allocated" } else { defertype = "heap-allocated" } - base.WarnfAt(n.Pos, "%s defer", defertype) + base.WarnfAt(n.Pos(), "%s defer", defertype) } if s.hasOpenDefers { - s.openDeferRecord(n.Left) + s.openDeferRecord(n.Left()) } else { d := callDefer - if n.Esc == EscNever { + if n.Esc() == EscNever { d = callDeferStack } - s.callResult(n.Left, d) + s.callResult(n.Left(), d) } case ir.OGO: - s.callResult(n.Left, callGo) + s.callResult(n.Left(), callGo) case ir.OAS2DOTTYPE: - res, resok := s.dottype(n.Right, true) + res, resok := s.dottype(n.Right(), true) deref := false - if !canSSAType(n.Right.Type) { + if !canSSAType(n.Right().Type()) { if res.Op != ssa.OpLoad { s.Fatalf("dottype of non-load") } @@ -1144,29 +1144,29 @@ func (s *state) stmt(n *ir.Node) { deref = true res = res.Args[0] } - s.assign(n.List.First(), res, deref, 0) - s.assign(n.List.Second(), resok, false, 0) + s.assign(n.List().First(), res, deref, 0) + s.assign(n.List().Second(), resok, false, 0) return case ir.OAS2FUNC: // We come here only when it is an intrinsic call returning two values. - if !isIntrinsicCall(n.Right) { - s.Fatalf("non-intrinsic AS2FUNC not expanded %v", n.Right) - } - v := s.intrinsicCall(n.Right) - v1 := s.newValue1(ssa.OpSelect0, n.List.First().Type, v) - v2 := s.newValue1(ssa.OpSelect1, n.List.Second().Type, v) - s.assign(n.List.First(), v1, false, 0) - s.assign(n.List.Second(), v2, false, 0) + if !isIntrinsicCall(n.Right()) { + s.Fatalf("non-intrinsic AS2FUNC not expanded %v", n.Right()) + } + v := s.intrinsicCall(n.Right()) + v1 := s.newValue1(ssa.OpSelect0, n.List().First().Type(), v) + v2 := s.newValue1(ssa.OpSelect1, n.List().Second().Type(), v) + s.assign(n.List().First(), v1, false, 0) + s.assign(n.List().Second(), v2, false, 0) return case ir.ODCL: - if n.Left.Class() == ir.PAUTOHEAP { + if n.Left().Class() == ir.PAUTOHEAP { s.Fatalf("DCL %v", n) } case ir.OLABEL: - sym := n.Sym + sym := n.Sym() lab := s.label(sym) // Associate label with its control flow node, if any @@ -1188,7 +1188,7 @@ func (s *state) stmt(n *ir.Node) { s.startBlock(lab.target) case ir.OGOTO: - sym := n.Sym + sym := n.Sym() lab := s.label(sym) if lab.target == nil { @@ -1200,7 +1200,7 @@ func (s *state) stmt(n *ir.Node) { b.AddEdgeTo(lab.target) case ir.OAS: - if n.Left == n.Right && n.Left.Op == ir.ONAME { + if n.Left() == n.Right() && n.Left().Op() == ir.ONAME { // An x=x assignment. No point in doing anything // here. In addition, skipping this assignment // prevents generating: @@ -1212,9 +1212,9 @@ func (s *state) stmt(n *ir.Node) { } // Evaluate RHS. - rhs := n.Right + rhs := n.Right() if rhs != nil { - switch rhs.Op { + switch rhs.Op() { case ir.OSTRUCTLIT, ir.OARRAYLIT, ir.OSLICELIT: // All literals with nonzero fields have already been // rewritten during walk. Any that remain are just T{} @@ -1227,27 +1227,27 @@ func (s *state) stmt(n *ir.Node) { // Check whether we're writing the result of an append back to the same slice. // If so, we handle it specially to avoid write barriers on the fast // (non-growth) path. - if !samesafeexpr(n.Left, rhs.List.First()) || base.Flag.N != 0 { + if !samesafeexpr(n.Left(), rhs.List().First()) || base.Flag.N != 0 { break } // If the slice can be SSA'd, it'll be on the stack, // so there will be no write barriers, // so there's no need to attempt to prevent them. - if s.canSSA(n.Left) { + if s.canSSA(n.Left()) { if base.Debug.Append > 0 { // replicating old diagnostic message - base.WarnfAt(n.Pos, "append: len-only update (in local slice)") + base.WarnfAt(n.Pos(), "append: len-only update (in local slice)") } break } if base.Debug.Append > 0 { - base.WarnfAt(n.Pos, "append: len-only update") + base.WarnfAt(n.Pos(), "append: len-only update") } s.append(rhs, true) return } } - if ir.IsBlank(n.Left) { + if ir.IsBlank(n.Left()) { // _ = rhs // Just evaluate rhs for side-effects. if rhs != nil { @@ -1257,10 +1257,10 @@ func (s *state) stmt(n *ir.Node) { } var t *types.Type - if n.Right != nil { - t = n.Right.Type + if n.Right() != nil { + t = n.Right().Type() } else { - t = n.Left.Type + t = n.Left().Type() } var r *ssa.Value @@ -1280,11 +1280,11 @@ func (s *state) stmt(n *ir.Node) { } var skip skipMask - if rhs != nil && (rhs.Op == ir.OSLICE || rhs.Op == ir.OSLICE3 || rhs.Op == ir.OSLICESTR) && samesafeexpr(rhs.Left, n.Left) { + if rhs != nil && (rhs.Op() == ir.OSLICE || rhs.Op() == ir.OSLICE3 || rhs.Op() == ir.OSLICESTR) && samesafeexpr(rhs.Left(), n.Left()) { // We're assigning a slicing operation back to its source. // Don't write back fields we aren't changing. See issue #14855. i, j, k := rhs.SliceBounds() - if i != nil && (i.Op == ir.OLITERAL && i.Val().Kind() == constant.Int && i.Int64Val() == 0) { + if i != nil && (i.Op() == ir.OLITERAL && i.Val().Kind() == constant.Int && i.Int64Val() == 0) { // [0:...] is the same as [:...] i = nil } @@ -1309,15 +1309,15 @@ func (s *state) stmt(n *ir.Node) { } } - s.assign(n.Left, r, deref, skip) + s.assign(n.Left(), r, deref, skip) case ir.OIF: - if ir.IsConst(n.Left, constant.Bool) { - s.stmtList(n.Left.Ninit) - if n.Left.BoolVal() { - s.stmtList(n.Nbody) + if ir.IsConst(n.Left(), constant.Bool) { + s.stmtList(n.Left().Init()) + if n.Left().BoolVal() { + s.stmtList(n.Body()) } else { - s.stmtList(n.Rlist) + s.stmtList(n.Rlist()) } break } @@ -1328,29 +1328,29 @@ func (s *state) stmt(n *ir.Node) { likely = 1 } var bThen *ssa.Block - if n.Nbody.Len() != 0 { + if n.Body().Len() != 0 { bThen = s.f.NewBlock(ssa.BlockPlain) } else { bThen = bEnd } var bElse *ssa.Block - if n.Rlist.Len() != 0 { + if n.Rlist().Len() != 0 { bElse = s.f.NewBlock(ssa.BlockPlain) } else { bElse = bEnd } - s.condBranch(n.Left, bThen, bElse, likely) + s.condBranch(n.Left(), bThen, bElse, likely) - if n.Nbody.Len() != 0 { + if n.Body().Len() != 0 { s.startBlock(bThen) - s.stmtList(n.Nbody) + s.stmtList(n.Body()) if b := s.endBlock(); b != nil { b.AddEdgeTo(bEnd) } } - if n.Rlist.Len() != 0 { + if n.Rlist().Len() != 0 { s.startBlock(bElse) - s.stmtList(n.Rlist) + s.stmtList(n.Rlist()) if b := s.endBlock(); b != nil { b.AddEdgeTo(bEnd) } @@ -1358,21 +1358,21 @@ func (s *state) stmt(n *ir.Node) { s.startBlock(bEnd) case ir.ORETURN: - s.stmtList(n.List) + s.stmtList(n.List()) b := s.exit() b.Pos = s.lastPos.WithIsStmt() case ir.ORETJMP: - s.stmtList(n.List) + s.stmtList(n.List()) b := s.exit() b.Kind = ssa.BlockRetJmp // override BlockRet - b.Aux = n.Sym.Linksym() + b.Aux = n.Sym().Linksym() case ir.OCONTINUE, ir.OBREAK: var to *ssa.Block - if n.Sym == nil { + if n.Sym() == nil { // plain break/continue - switch n.Op { + switch n.Op() { case ir.OCONTINUE: to = s.continueTo case ir.OBREAK: @@ -1380,9 +1380,9 @@ func (s *state) stmt(n *ir.Node) { } } else { // labeled break/continue; look up the target - sym := n.Sym + sym := n.Sym() lab := s.label(sym) - switch n.Op { + switch n.Op() { case ir.OCONTINUE: to = lab.continueTarget case ir.OBREAK: @@ -1406,16 +1406,16 @@ func (s *state) stmt(n *ir.Node) { bEnd := s.f.NewBlock(ssa.BlockPlain) // ensure empty for loops have correct position; issue #30167 - bBody.Pos = n.Pos + bBody.Pos = n.Pos() // first, jump to condition test (OFOR) or body (OFORUNTIL) b := s.endBlock() - if n.Op == ir.OFOR { + if n.Op() == ir.OFOR { b.AddEdgeTo(bCond) // generate code to test condition s.startBlock(bCond) - if n.Left != nil { - s.condBranch(n.Left, bBody, bEnd, 1) + if n.Left() != nil { + s.condBranch(n.Left(), bBody, bEnd, 1) } else { b := s.endBlock() b.Kind = ssa.BlockPlain @@ -1440,7 +1440,7 @@ func (s *state) stmt(n *ir.Node) { // generate body s.startBlock(bBody) - s.stmtList(n.Nbody) + s.stmtList(n.Body()) // tear down continue/break s.continueTo = prevContinue @@ -1457,15 +1457,15 @@ func (s *state) stmt(n *ir.Node) { // generate incr (and, for OFORUNTIL, condition) s.startBlock(bIncr) - if n.Right != nil { - s.stmt(n.Right) + if n.Right() != nil { + s.stmt(n.Right()) } - if n.Op == ir.OFOR { + if n.Op() == ir.OFOR { if b := s.endBlock(); b != nil { b.AddEdgeTo(bCond) // It can happen that bIncr ends in a block containing only VARKILL, // and that muddles the debugging experience. - if n.Op != ir.OFORUNTIL && b.Pos == src.NoXPos { + if n.Op() != ir.OFORUNTIL && b.Pos == src.NoXPos { b.Pos = bCond.Pos } } @@ -1473,10 +1473,10 @@ func (s *state) stmt(n *ir.Node) { // bCond is unused in OFORUNTIL, so repurpose it. bLateIncr := bCond // test condition - s.condBranch(n.Left, bLateIncr, bEnd, 1) + s.condBranch(n.Left(), bLateIncr, bEnd, 1) // generate late increment s.startBlock(bLateIncr) - s.stmtList(n.List) + s.stmtList(n.List()) s.endBlock().AddEdgeTo(bBody) } @@ -1496,7 +1496,7 @@ func (s *state) stmt(n *ir.Node) { } // generate body code - s.stmtList(n.Nbody) + s.stmtList(n.Body()) s.breakTo = prevBreak if lab != nil { @@ -1514,39 +1514,39 @@ func (s *state) stmt(n *ir.Node) { s.startBlock(bEnd) case ir.OVARDEF: - if !s.canSSA(n.Left) { - s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, n.Left, s.mem(), false) + if !s.canSSA(n.Left()) { + s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, n.Left(), s.mem(), false) } case ir.OVARKILL: // Insert a varkill op to record that a variable is no longer live. // We only care about liveness info at call sites, so putting the // varkill in the store chain is enough to keep it correctly ordered // with respect to call ops. - if !s.canSSA(n.Left) { - s.vars[memVar] = s.newValue1Apos(ssa.OpVarKill, types.TypeMem, n.Left, s.mem(), false) + if !s.canSSA(n.Left()) { + s.vars[memVar] = s.newValue1Apos(ssa.OpVarKill, types.TypeMem, n.Left(), s.mem(), false) } case ir.OVARLIVE: // Insert a varlive op to record that a variable is still live. - if !n.Left.Name.Addrtaken() { - s.Fatalf("VARLIVE variable %v must have Addrtaken set", n.Left) + if !n.Left().Name().Addrtaken() { + s.Fatalf("VARLIVE variable %v must have Addrtaken set", n.Left()) } - switch n.Left.Class() { + switch n.Left().Class() { case ir.PAUTO, ir.PPARAM, ir.PPARAMOUT: default: - s.Fatalf("VARLIVE variable %v must be Auto or Arg", n.Left) + s.Fatalf("VARLIVE variable %v must be Auto or Arg", n.Left()) } - s.vars[memVar] = s.newValue1A(ssa.OpVarLive, types.TypeMem, n.Left, s.mem()) + s.vars[memVar] = s.newValue1A(ssa.OpVarLive, types.TypeMem, n.Left(), s.mem()) case ir.OCHECKNIL: - p := s.expr(n.Left) + p := s.expr(n.Left()) s.nilCheck(p) case ir.OINLMARK: - s.newValue1I(ssa.OpInlMark, types.TypeVoid, n.Xoffset, s.mem()) + s.newValue1I(ssa.OpInlMark, types.TypeVoid, n.Offset(), s.mem()) default: - s.Fatalf("unhandled stmt %v", n.Op) + s.Fatalf("unhandled stmt %v", n.Op()) } } @@ -1576,14 +1576,14 @@ func (s *state) exit() *ssa.Block { // Run exit code. Typically, this code copies heap-allocated PPARAMOUT // variables back to the stack. - s.stmtList(s.curfn.Func.Exit) + s.stmtList(s.curfn.Func().Exit) // Store SSAable PPARAMOUT variables back to stack locations. for _, n := range s.returns { addr := s.decladdrs[n] - val := s.variable(n, n.Type) + val := s.variable(n, n.Type()) s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem()) - s.store(n.Type, addr, val) + s.store(n.Type(), addr, val) // TODO: if val is ever spilled, we'd like to use the // PPARAMOUT slot for spilling it. That won't happen // currently. @@ -2003,44 +2003,44 @@ func (s *state) expr(n *ir.Node) *ssa.Value { if hasUniquePos(n) { // ONAMEs and named OLITERALs have the line number // of the decl, not the use. See issue 14742. - s.pushLine(n.Pos) + s.pushLine(n.Pos()) defer s.popLine() } - s.stmtList(n.Ninit) - switch n.Op { + s.stmtList(n.Init()) + switch n.Op() { case ir.OBYTES2STRTMP: - slice := s.expr(n.Left) + slice := s.expr(n.Left()) ptr := s.newValue1(ssa.OpSlicePtr, s.f.Config.Types.BytePtr, slice) len := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], slice) - return s.newValue2(ssa.OpStringMake, n.Type, ptr, len) + return s.newValue2(ssa.OpStringMake, n.Type(), ptr, len) case ir.OSTR2BYTESTMP: - str := s.expr(n.Left) + str := s.expr(n.Left()) ptr := s.newValue1(ssa.OpStringPtr, s.f.Config.Types.BytePtr, str) len := s.newValue1(ssa.OpStringLen, types.Types[types.TINT], str) - return s.newValue3(ssa.OpSliceMake, n.Type, ptr, len, len) + return s.newValue3(ssa.OpSliceMake, n.Type(), ptr, len, len) case ir.OCFUNC: - aux := n.Left.Sym.Linksym() - return s.entryNewValue1A(ssa.OpAddr, n.Type, aux, s.sb) + aux := n.Left().Sym().Linksym() + return s.entryNewValue1A(ssa.OpAddr, n.Type(), aux, s.sb) case ir.OMETHEXPR: - sym := funcsym(n.Sym).Linksym() - return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), sym, s.sb) + sym := funcsym(n.Sym()).Linksym() + return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type()), sym, s.sb) case ir.ONAME: if n.Class() == ir.PFUNC { // "value" of a function is the address of the function's closure - sym := funcsym(n.Sym).Linksym() - return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), sym, s.sb) + sym := funcsym(n.Sym()).Linksym() + return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type()), sym, s.sb) } if s.canSSA(n) { - return s.variable(n, n.Type) + return s.variable(n, n.Type()) } addr := s.addr(n) - return s.load(n.Type, addr) + return s.load(n.Type(), addr) case ir.OCLOSUREVAR: addr := s.addr(n) - return s.load(n.Type, addr) + return s.load(n.Type(), addr) case ir.ONIL: - t := n.Type + t := n.Type() switch { case t.IsSlice(): return s.constSlice(t) @@ -2052,55 +2052,55 @@ func (s *state) expr(n *ir.Node) *ssa.Value { case ir.OLITERAL: switch u := n.Val(); u.Kind() { case constant.Int: - i := ir.Int64Val(n.Type, u) - switch n.Type.Size() { + i := ir.Int64Val(n.Type(), u) + switch n.Type().Size() { case 1: - return s.constInt8(n.Type, int8(i)) + return s.constInt8(n.Type(), int8(i)) case 2: - return s.constInt16(n.Type, int16(i)) + return s.constInt16(n.Type(), int16(i)) case 4: - return s.constInt32(n.Type, int32(i)) + return s.constInt32(n.Type(), int32(i)) case 8: - return s.constInt64(n.Type, i) + return s.constInt64(n.Type(), i) default: - s.Fatalf("bad integer size %d", n.Type.Size()) + s.Fatalf("bad integer size %d", n.Type().Size()) return nil } case constant.String: i := constant.StringVal(u) if i == "" { - return s.constEmptyString(n.Type) + return s.constEmptyString(n.Type()) } - return s.entryNewValue0A(ssa.OpConstString, n.Type, i) + return s.entryNewValue0A(ssa.OpConstString, n.Type(), i) case constant.Bool: return s.constBool(constant.BoolVal(u)) case constant.Float: f, _ := constant.Float64Val(u) - switch n.Type.Size() { + switch n.Type().Size() { case 4: - return s.constFloat32(n.Type, f) + return s.constFloat32(n.Type(), f) case 8: - return s.constFloat64(n.Type, f) + return s.constFloat64(n.Type(), f) default: - s.Fatalf("bad float size %d", n.Type.Size()) + s.Fatalf("bad float size %d", n.Type().Size()) return nil } case constant.Complex: re, _ := constant.Float64Val(constant.Real(u)) im, _ := constant.Float64Val(constant.Imag(u)) - switch n.Type.Size() { + switch n.Type().Size() { case 8: pt := types.Types[types.TFLOAT32] - return s.newValue2(ssa.OpComplexMake, n.Type, + return s.newValue2(ssa.OpComplexMake, n.Type(), s.constFloat32(pt, re), s.constFloat32(pt, im)) case 16: pt := types.Types[types.TFLOAT64] - return s.newValue2(ssa.OpComplexMake, n.Type, + return s.newValue2(ssa.OpComplexMake, n.Type(), s.constFloat64(pt, re), s.constFloat64(pt, im)) default: - s.Fatalf("bad complex size %d", n.Type.Size()) + s.Fatalf("bad complex size %d", n.Type().Size()) return nil } default: @@ -2108,12 +2108,12 @@ func (s *state) expr(n *ir.Node) *ssa.Value { return nil } case ir.OCONVNOP: - to := n.Type - from := n.Left.Type + to := n.Type() + from := n.Left().Type() // Assume everything will work out, so set up our return value. // Anything interesting that happens from here is a fatal. - x := s.expr(n.Left) + x := s.expr(n.Left()) // Special case for not confusing GC and liveness. // We don't want pointers accidentally classified @@ -2173,12 +2173,12 @@ func (s *state) expr(n *ir.Node) *ssa.Value { return v case ir.OCONV: - x := s.expr(n.Left) - ft := n.Left.Type // from type - tt := n.Type // to type + x := s.expr(n.Left()) + ft := n.Left().Type() // from type + tt := n.Type() // to type if ft.IsBoolean() && tt.IsKind(types.TUINT8) { // Bool -> uint8 is generated internally when indexing into runtime.staticbyte. - return s.newValue1(ssa.OpCopy, n.Type, x) + return s.newValue1(ssa.OpCopy, n.Type(), x) } if ft.IsInteger() && tt.IsInteger() { var op ssa.Op @@ -2239,7 +2239,7 @@ func (s *state) expr(n *ir.Node) *ssa.Value { s.Fatalf("weird integer sign extension %v -> %v", ft, tt) } } - return s.newValue1(op, n.Type, x) + return s.newValue1(op, n.Type(), x) } if ft.IsFloat() || tt.IsFloat() { @@ -2286,12 +2286,12 @@ func (s *state) expr(n *ir.Node) *ssa.Value { if op2 == ssa.OpCopy { return x } - return s.newValueOrSfCall1(op2, n.Type, x) + return s.newValueOrSfCall1(op2, n.Type(), x) } if op2 == ssa.OpCopy { - return s.newValueOrSfCall1(op1, n.Type, x) + return s.newValueOrSfCall1(op1, n.Type(), x) } - return s.newValueOrSfCall1(op2, n.Type, s.newValueOrSfCall1(op1, types.Types[it], x)) + return s.newValueOrSfCall1(op2, n.Type(), s.newValueOrSfCall1(op1, types.Types[it], x)) } // Tricky 64-bit unsigned cases. if ft.IsInteger() { @@ -2340,7 +2340,7 @@ func (s *state) expr(n *ir.Node) *ssa.Value { s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexImag, ftp, x))) } - s.Fatalf("unhandled OCONV %s -> %s", n.Left.Type.Etype, n.Type.Etype) + s.Fatalf("unhandled OCONV %s -> %s", n.Left().Type().Etype, n.Type().Etype) return nil case ir.ODOTTYPE: @@ -2349,46 +2349,46 @@ func (s *state) expr(n *ir.Node) *ssa.Value { // binary ops case ir.OLT, ir.OEQ, ir.ONE, ir.OLE, ir.OGE, ir.OGT: - a := s.expr(n.Left) - b := s.expr(n.Right) - if n.Left.Type.IsComplex() { - pt := floatForComplex(n.Left.Type) + a := s.expr(n.Left()) + b := s.expr(n.Right()) + if n.Left().Type().IsComplex() { + pt := floatForComplex(n.Left().Type()) op := s.ssaOp(ir.OEQ, pt) r := s.newValueOrSfCall2(op, types.Types[types.TBOOL], s.newValue1(ssa.OpComplexReal, pt, a), s.newValue1(ssa.OpComplexReal, pt, b)) i := s.newValueOrSfCall2(op, types.Types[types.TBOOL], s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b)) c := s.newValue2(ssa.OpAndB, types.Types[types.TBOOL], r, i) - switch n.Op { + switch n.Op() { case ir.OEQ: return c case ir.ONE: return s.newValue1(ssa.OpNot, types.Types[types.TBOOL], c) default: - s.Fatalf("ordered complex compare %v", n.Op) + s.Fatalf("ordered complex compare %v", n.Op()) } } // Convert OGE and OGT into OLE and OLT. - op := n.Op + op := n.Op() switch op { case ir.OGE: op, a, b = ir.OLE, b, a case ir.OGT: op, a, b = ir.OLT, b, a } - if n.Left.Type.IsFloat() { + if n.Left().Type().IsFloat() { // float comparison - return s.newValueOrSfCall2(s.ssaOp(op, n.Left.Type), types.Types[types.TBOOL], a, b) + return s.newValueOrSfCall2(s.ssaOp(op, n.Left().Type()), types.Types[types.TBOOL], a, b) } // integer comparison - return s.newValue2(s.ssaOp(op, n.Left.Type), types.Types[types.TBOOL], a, b) + return s.newValue2(s.ssaOp(op, n.Left().Type()), types.Types[types.TBOOL], a, b) case ir.OMUL: - a := s.expr(n.Left) - b := s.expr(n.Right) - if n.Type.IsComplex() { + a := s.expr(n.Left()) + b := s.expr(n.Right()) + if n.Type().IsComplex() { mulop := ssa.OpMul64F addop := ssa.OpAdd64F subop := ssa.OpSub64F - pt := floatForComplex(n.Type) // Could be Float32 or Float64 + pt := floatForComplex(n.Type()) // Could be Float32 or Float64 wt := types.Types[types.TFLOAT64] // Compute in Float64 to minimize cancellation error areal := s.newValue1(ssa.OpComplexReal, pt, a) @@ -2411,19 +2411,19 @@ func (s *state) expr(n *ir.Node) *ssa.Value { ximag = s.newValueOrSfCall1(ssa.OpCvt64Fto32F, pt, ximag) } - return s.newValue2(ssa.OpComplexMake, n.Type, xreal, ximag) + return s.newValue2(ssa.OpComplexMake, n.Type(), xreal, ximag) } - if n.Type.IsFloat() { - return s.newValueOrSfCall2(s.ssaOp(n.Op, n.Type), a.Type, a, b) + if n.Type().IsFloat() { + return s.newValueOrSfCall2(s.ssaOp(n.Op(), n.Type()), a.Type, a, b) } - return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b) + return s.newValue2(s.ssaOp(n.Op(), n.Type()), a.Type, a, b) case ir.ODIV: - a := s.expr(n.Left) - b := s.expr(n.Right) - if n.Type.IsComplex() { + a := s.expr(n.Left()) + b := s.expr(n.Right()) + if n.Type().IsComplex() { // TODO this is not executed because the front-end substitutes a runtime call. // That probably ought to change; with modest optimization the widen/narrow // conversions could all be elided in larger expression trees. @@ -2431,7 +2431,7 @@ func (s *state) expr(n *ir.Node) *ssa.Value { addop := ssa.OpAdd64F subop := ssa.OpSub64F divop := ssa.OpDiv64F - pt := floatForComplex(n.Type) // Could be Float32 or Float64 + pt := floatForComplex(n.Type()) // Could be Float32 or Float64 wt := types.Types[types.TFLOAT64] // Compute in Float64 to minimize cancellation error areal := s.newValue1(ssa.OpComplexReal, pt, a) @@ -2461,49 +2461,49 @@ func (s *state) expr(n *ir.Node) *ssa.Value { xreal = s.newValueOrSfCall1(ssa.OpCvt64Fto32F, pt, xreal) ximag = s.newValueOrSfCall1(ssa.OpCvt64Fto32F, pt, ximag) } - return s.newValue2(ssa.OpComplexMake, n.Type, xreal, ximag) + return s.newValue2(ssa.OpComplexMake, n.Type(), xreal, ximag) } - if n.Type.IsFloat() { - return s.newValueOrSfCall2(s.ssaOp(n.Op, n.Type), a.Type, a, b) + if n.Type().IsFloat() { + return s.newValueOrSfCall2(s.ssaOp(n.Op(), n.Type()), a.Type, a, b) } return s.intDivide(n, a, b) case ir.OMOD: - a := s.expr(n.Left) - b := s.expr(n.Right) + a := s.expr(n.Left()) + b := s.expr(n.Right()) return s.intDivide(n, a, b) case ir.OADD, ir.OSUB: - a := s.expr(n.Left) - b := s.expr(n.Right) - if n.Type.IsComplex() { - pt := floatForComplex(n.Type) - op := s.ssaOp(n.Op, pt) - return s.newValue2(ssa.OpComplexMake, n.Type, + a := s.expr(n.Left()) + b := s.expr(n.Right()) + if n.Type().IsComplex() { + pt := floatForComplex(n.Type()) + op := s.ssaOp(n.Op(), pt) + return s.newValue2(ssa.OpComplexMake, n.Type(), s.newValueOrSfCall2(op, pt, s.newValue1(ssa.OpComplexReal, pt, a), s.newValue1(ssa.OpComplexReal, pt, b)), s.newValueOrSfCall2(op, pt, s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b))) } - if n.Type.IsFloat() { - return s.newValueOrSfCall2(s.ssaOp(n.Op, n.Type), a.Type, a, b) + if n.Type().IsFloat() { + return s.newValueOrSfCall2(s.ssaOp(n.Op(), n.Type()), a.Type, a, b) } - return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b) + return s.newValue2(s.ssaOp(n.Op(), n.Type()), a.Type, a, b) case ir.OAND, ir.OOR, ir.OXOR: - a := s.expr(n.Left) - b := s.expr(n.Right) - return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b) + a := s.expr(n.Left()) + b := s.expr(n.Right()) + return s.newValue2(s.ssaOp(n.Op(), n.Type()), a.Type, a, b) case ir.OANDNOT: - a := s.expr(n.Left) - b := s.expr(n.Right) + a := s.expr(n.Left()) + b := s.expr(n.Right()) b = s.newValue1(s.ssaOp(ir.OBITNOT, b.Type), b.Type, b) - return s.newValue2(s.ssaOp(ir.OAND, n.Type), a.Type, a, b) + return s.newValue2(s.ssaOp(ir.OAND, n.Type()), a.Type, a, b) case ir.OLSH, ir.ORSH: - a := s.expr(n.Left) - b := s.expr(n.Right) + a := s.expr(n.Left()) + b := s.expr(n.Right()) bt := b.Type if bt.IsSigned() { cmp := s.newValue2(s.ssaOp(ir.OLE, bt), types.Types[types.TBOOL], s.zeroVal(bt), b) s.check(cmp, panicshift) bt = bt.ToUnsigned() } - return s.newValue2(s.ssaShiftOp(n.Op, n.Type, bt), a.Type, a, b) + return s.newValue2(s.ssaShiftOp(n.Op(), n.Type(), bt), a.Type, a, b) case ir.OANDAND, ir.OOROR: // To implement OANDAND (and OOROR), we introduce a // new temporary variable to hold the result. The @@ -2518,7 +2518,7 @@ func (s *state) expr(n *ir.Node) *ssa.Value { // } // Using var in the subsequent block introduces the // necessary phi variable. - el := s.expr(n.Left) + el := s.expr(n.Left()) s.vars[n] = el b := s.endBlock() @@ -2531,16 +2531,16 @@ func (s *state) expr(n *ir.Node) *ssa.Value { bRight := s.f.NewBlock(ssa.BlockPlain) bResult := s.f.NewBlock(ssa.BlockPlain) - if n.Op == ir.OANDAND { + if n.Op() == ir.OANDAND { b.AddEdgeTo(bRight) b.AddEdgeTo(bResult) - } else if n.Op == ir.OOROR { + } else if n.Op() == ir.OOROR { b.AddEdgeTo(bResult) b.AddEdgeTo(bRight) } s.startBlock(bRight) - er := s.expr(n.Right) + er := s.expr(n.Right()) s.vars[n] = er b = s.endBlock() @@ -2549,65 +2549,65 @@ func (s *state) expr(n *ir.Node) *ssa.Value { s.startBlock(bResult) return s.variable(n, types.Types[types.TBOOL]) case ir.OCOMPLEX: - r := s.expr(n.Left) - i := s.expr(n.Right) - return s.newValue2(ssa.OpComplexMake, n.Type, r, i) + r := s.expr(n.Left()) + i := s.expr(n.Right()) + return s.newValue2(ssa.OpComplexMake, n.Type(), r, i) // unary ops case ir.ONEG: - a := s.expr(n.Left) - if n.Type.IsComplex() { - tp := floatForComplex(n.Type) - negop := s.ssaOp(n.Op, tp) - return s.newValue2(ssa.OpComplexMake, n.Type, + a := s.expr(n.Left()) + if n.Type().IsComplex() { + tp := floatForComplex(n.Type()) + negop := s.ssaOp(n.Op(), tp) + return s.newValue2(ssa.OpComplexMake, n.Type(), s.newValue1(negop, tp, s.newValue1(ssa.OpComplexReal, tp, a)), s.newValue1(negop, tp, s.newValue1(ssa.OpComplexImag, tp, a))) } - return s.newValue1(s.ssaOp(n.Op, n.Type), a.Type, a) + return s.newValue1(s.ssaOp(n.Op(), n.Type()), a.Type, a) case ir.ONOT, ir.OBITNOT: - a := s.expr(n.Left) - return s.newValue1(s.ssaOp(n.Op, n.Type), a.Type, a) + a := s.expr(n.Left()) + return s.newValue1(s.ssaOp(n.Op(), n.Type()), a.Type, a) case ir.OIMAG, ir.OREAL: - a := s.expr(n.Left) - return s.newValue1(s.ssaOp(n.Op, n.Left.Type), n.Type, a) + a := s.expr(n.Left()) + return s.newValue1(s.ssaOp(n.Op(), n.Left().Type()), n.Type(), a) case ir.OPLUS: - return s.expr(n.Left) + return s.expr(n.Left()) case ir.OADDR: - return s.addr(n.Left) + return s.addr(n.Left()) case ir.ORESULT: if s.prevCall == nil || s.prevCall.Op != ssa.OpStaticLECall && s.prevCall.Op != ssa.OpInterLECall && s.prevCall.Op != ssa.OpClosureLECall { // Do the old thing - addr := s.constOffPtrSP(types.NewPtr(n.Type), n.Xoffset) - return s.rawLoad(n.Type, addr) + addr := s.constOffPtrSP(types.NewPtr(n.Type()), n.Offset()) + return s.rawLoad(n.Type(), addr) } - which := s.prevCall.Aux.(*ssa.AuxCall).ResultForOffset(n.Xoffset) + which := s.prevCall.Aux.(*ssa.AuxCall).ResultForOffset(n.Offset()) if which == -1 { // Do the old thing // TODO: Panic instead. - addr := s.constOffPtrSP(types.NewPtr(n.Type), n.Xoffset) - return s.rawLoad(n.Type, addr) + addr := s.constOffPtrSP(types.NewPtr(n.Type()), n.Offset()) + return s.rawLoad(n.Type(), addr) } - if canSSAType(n.Type) { - return s.newValue1I(ssa.OpSelectN, n.Type, which, s.prevCall) + if canSSAType(n.Type()) { + return s.newValue1I(ssa.OpSelectN, n.Type(), which, s.prevCall) } else { - addr := s.newValue1I(ssa.OpSelectNAddr, types.NewPtr(n.Type), which, s.prevCall) - return s.rawLoad(n.Type, addr) + addr := s.newValue1I(ssa.OpSelectNAddr, types.NewPtr(n.Type()), which, s.prevCall) + return s.rawLoad(n.Type(), addr) } case ir.ODEREF: - p := s.exprPtr(n.Left, n.Bounded(), n.Pos) - return s.load(n.Type, p) + p := s.exprPtr(n.Left(), n.Bounded(), n.Pos()) + return s.load(n.Type(), p) case ir.ODOT: - if n.Left.Op == ir.OSTRUCTLIT { + if n.Left().Op() == ir.OSTRUCTLIT { // All literals with nonzero fields have already been // rewritten during walk. Any that remain are just T{} // or equivalents. Use the zero value. - if !isZero(n.Left) { - s.Fatalf("literal with nonzero value in SSA: %v", n.Left) + if !isZero(n.Left()) { + s.Fatalf("literal with nonzero value in SSA: %v", n.Left()) } - return s.zeroVal(n.Type) + return s.zeroVal(n.Type()) } // If n is addressable and can't be represented in // SSA, then load just the selected field. This @@ -2615,110 +2615,110 @@ func (s *state) expr(n *ir.Node) *ssa.Value { // instrumentation. if islvalue(n) && !s.canSSA(n) { p := s.addr(n) - return s.load(n.Type, p) + return s.load(n.Type(), p) } - v := s.expr(n.Left) - return s.newValue1I(ssa.OpStructSelect, n.Type, int64(fieldIdx(n)), v) + v := s.expr(n.Left()) + return s.newValue1I(ssa.OpStructSelect, n.Type(), int64(fieldIdx(n)), v) case ir.ODOTPTR: - p := s.exprPtr(n.Left, n.Bounded(), n.Pos) - p = s.newValue1I(ssa.OpOffPtr, types.NewPtr(n.Type), n.Xoffset, p) - return s.load(n.Type, p) + p := s.exprPtr(n.Left(), n.Bounded(), n.Pos()) + p = s.newValue1I(ssa.OpOffPtr, types.NewPtr(n.Type()), n.Offset(), p) + return s.load(n.Type(), p) case ir.OINDEX: switch { - case n.Left.Type.IsString(): - if n.Bounded() && ir.IsConst(n.Left, constant.String) && ir.IsConst(n.Right, constant.Int) { + case n.Left().Type().IsString(): + if n.Bounded() && ir.IsConst(n.Left(), constant.String) && ir.IsConst(n.Right(), constant.Int) { // Replace "abc"[1] with 'b'. // Delayed until now because "abc"[1] is not an ideal constant. // See test/fixedbugs/issue11370.go. - return s.newValue0I(ssa.OpConst8, types.Types[types.TUINT8], int64(int8(n.Left.StringVal()[n.Right.Int64Val()]))) + return s.newValue0I(ssa.OpConst8, types.Types[types.TUINT8], int64(int8(n.Left().StringVal()[n.Right().Int64Val()]))) } - a := s.expr(n.Left) - i := s.expr(n.Right) + a := s.expr(n.Left()) + i := s.expr(n.Right()) len := s.newValue1(ssa.OpStringLen, types.Types[types.TINT], a) i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded()) ptrtyp := s.f.Config.Types.BytePtr ptr := s.newValue1(ssa.OpStringPtr, ptrtyp, a) - if ir.IsConst(n.Right, constant.Int) { - ptr = s.newValue1I(ssa.OpOffPtr, ptrtyp, n.Right.Int64Val(), ptr) + if ir.IsConst(n.Right(), constant.Int) { + ptr = s.newValue1I(ssa.OpOffPtr, ptrtyp, n.Right().Int64Val(), ptr) } else { ptr = s.newValue2(ssa.OpAddPtr, ptrtyp, ptr, i) } return s.load(types.Types[types.TUINT8], ptr) - case n.Left.Type.IsSlice(): + case n.Left().Type().IsSlice(): p := s.addr(n) - return s.load(n.Left.Type.Elem(), p) - case n.Left.Type.IsArray(): - if canSSAType(n.Left.Type) { + return s.load(n.Left().Type().Elem(), p) + case n.Left().Type().IsArray(): + if canSSAType(n.Left().Type()) { // SSA can handle arrays of length at most 1. - bound := n.Left.Type.NumElem() - a := s.expr(n.Left) - i := s.expr(n.Right) + bound := n.Left().Type().NumElem() + a := s.expr(n.Left()) + i := s.expr(n.Right()) if bound == 0 { // Bounds check will never succeed. Might as well // use constants for the bounds check. z := s.constInt(types.Types[types.TINT], 0) s.boundsCheck(z, z, ssa.BoundsIndex, false) // The return value won't be live, return junk. - return s.newValue0(ssa.OpUnknown, n.Type) + return s.newValue0(ssa.OpUnknown, n.Type()) } len := s.constInt(types.Types[types.TINT], bound) s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded()) // checks i == 0 - return s.newValue1I(ssa.OpArraySelect, n.Type, 0, a) + return s.newValue1I(ssa.OpArraySelect, n.Type(), 0, a) } p := s.addr(n) - return s.load(n.Left.Type.Elem(), p) + return s.load(n.Left().Type().Elem(), p) default: - s.Fatalf("bad type for index %v", n.Left.Type) + s.Fatalf("bad type for index %v", n.Left().Type()) return nil } case ir.OLEN, ir.OCAP: switch { - case n.Left.Type.IsSlice(): + case n.Left().Type().IsSlice(): op := ssa.OpSliceLen - if n.Op == ir.OCAP { + if n.Op() == ir.OCAP { op = ssa.OpSliceCap } - return s.newValue1(op, types.Types[types.TINT], s.expr(n.Left)) - case n.Left.Type.IsString(): // string; not reachable for OCAP - return s.newValue1(ssa.OpStringLen, types.Types[types.TINT], s.expr(n.Left)) - case n.Left.Type.IsMap(), n.Left.Type.IsChan(): - return s.referenceTypeBuiltin(n, s.expr(n.Left)) + return s.newValue1(op, types.Types[types.TINT], s.expr(n.Left())) + case n.Left().Type().IsString(): // string; not reachable for OCAP + return s.newValue1(ssa.OpStringLen, types.Types[types.TINT], s.expr(n.Left())) + case n.Left().Type().IsMap(), n.Left().Type().IsChan(): + return s.referenceTypeBuiltin(n, s.expr(n.Left())) default: // array - return s.constInt(types.Types[types.TINT], n.Left.Type.NumElem()) + return s.constInt(types.Types[types.TINT], n.Left().Type().NumElem()) } case ir.OSPTR: - a := s.expr(n.Left) - if n.Left.Type.IsSlice() { - return s.newValue1(ssa.OpSlicePtr, n.Type, a) + a := s.expr(n.Left()) + if n.Left().Type().IsSlice() { + return s.newValue1(ssa.OpSlicePtr, n.Type(), a) } else { - return s.newValue1(ssa.OpStringPtr, n.Type, a) + return s.newValue1(ssa.OpStringPtr, n.Type(), a) } case ir.OITAB: - a := s.expr(n.Left) - return s.newValue1(ssa.OpITab, n.Type, a) + a := s.expr(n.Left()) + return s.newValue1(ssa.OpITab, n.Type(), a) case ir.OIDATA: - a := s.expr(n.Left) - return s.newValue1(ssa.OpIData, n.Type, a) + a := s.expr(n.Left()) + return s.newValue1(ssa.OpIData, n.Type(), a) case ir.OEFACE: - tab := s.expr(n.Left) - data := s.expr(n.Right) - return s.newValue2(ssa.OpIMake, n.Type, tab, data) + tab := s.expr(n.Left()) + data := s.expr(n.Right()) + return s.newValue2(ssa.OpIMake, n.Type(), tab, data) case ir.OSLICEHEADER: - p := s.expr(n.Left) - l := s.expr(n.List.First()) - c := s.expr(n.List.Second()) - return s.newValue3(ssa.OpSliceMake, n.Type, p, l, c) + p := s.expr(n.Left()) + l := s.expr(n.List().First()) + c := s.expr(n.List().Second()) + return s.newValue3(ssa.OpSliceMake, n.Type(), p, l, c) case ir.OSLICE, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR: - v := s.expr(n.Left) + v := s.expr(n.Left()) var i, j, k *ssa.Value low, high, max := n.SliceBounds() if low != nil { @@ -2731,10 +2731,10 @@ func (s *state) expr(n *ir.Node) *ssa.Value { k = s.expr(max) } p, l, c := s.slice(v, i, j, k, n.Bounded()) - return s.newValue3(ssa.OpSliceMake, n.Type, p, l, c) + return s.newValue3(ssa.OpSliceMake, n.Type(), p, l, c) case ir.OSLICESTR: - v := s.expr(n.Left) + v := s.expr(n.Left()) var i, j *ssa.Value low, high, _ := n.SliceBounds() if low != nil { @@ -2744,7 +2744,7 @@ func (s *state) expr(n *ir.Node) *ssa.Value { j = s.expr(high) } p, l, _ := s.slice(v, i, j, nil, n.Bounded()) - return s.newValue2(ssa.OpStringMake, n.Type, p, l) + return s.newValue2(ssa.OpStringMake, n.Type(), p, l) case ir.OCALLFUNC: if isIntrinsicCall(n) { @@ -2756,7 +2756,7 @@ func (s *state) expr(n *ir.Node) *ssa.Value { return s.callResult(n, callNormal) case ir.OGETG: - return s.newValue1(ssa.OpGetG, n.Type, s.mem()) + return s.newValue1(ssa.OpGetG, n.Type(), s.mem()) case ir.OAPPEND: return s.append(n, false) @@ -2768,18 +2768,18 @@ func (s *state) expr(n *ir.Node) *ssa.Value { if !isZero(n) { s.Fatalf("literal with nonzero value in SSA: %v", n) } - return s.zeroVal(n.Type) + return s.zeroVal(n.Type()) case ir.ONEWOBJ: - if n.Type.Elem().Size() == 0 { - return s.newValue1A(ssa.OpAddr, n.Type, zerobaseSym, s.sb) + if n.Type().Elem().Size() == 0 { + return s.newValue1A(ssa.OpAddr, n.Type(), zerobaseSym, s.sb) } - typ := s.expr(n.Left) - vv := s.rtcall(newobject, true, []*types.Type{n.Type}, typ) + typ := s.expr(n.Left()) + vv := s.rtcall(newobject, true, []*types.Type{n.Type()}, typ) return vv[0] default: - s.Fatalf("unhandled expr %v", n.Op) + s.Fatalf("unhandled expr %v", n.Op()) return nil } } @@ -2824,16 +2824,16 @@ func (s *state) append(n *ir.Node, inplace bool) *ssa.Value { // *(ptr+len+1) = e2 // *(ptr+len+2) = e3 - et := n.Type.Elem() + et := n.Type().Elem() pt := types.NewPtr(et) // Evaluate slice - sn := n.List.First() // the slice node is the first in the list + sn := n.List().First() // the slice node is the first in the list var slice, addr *ssa.Value if inplace { addr = s.addr(sn) - slice = s.load(n.Type, addr) + slice = s.load(n.Type(), addr) } else { slice = s.expr(sn) } @@ -2843,7 +2843,7 @@ func (s *state) append(n *ir.Node, inplace bool) *ssa.Value { assign := s.f.NewBlock(ssa.BlockPlain) // Decide if we need to grow - nargs := int64(n.List.Len() - 1) + nargs := int64(n.List().Len() - 1) p := s.newValue1(ssa.OpSlicePtr, pt, slice) l := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], slice) c := s.newValue1(ssa.OpSliceCap, types.Types[types.TINT], slice) @@ -2868,11 +2868,11 @@ func (s *state) append(n *ir.Node, inplace bool) *ssa.Value { // Call growslice s.startBlock(grow) - taddr := s.expr(n.Left) + taddr := s.expr(n.Left()) r := s.rtcall(growslice, true, []*types.Type{pt, types.Types[types.TINT], types.Types[types.TINT]}, taddr, p, l, c, nl) if inplace { - if sn.Op == ir.ONAME && sn.Class() != ir.PEXTERN { + if sn.Op() == ir.ONAME && sn.Class() != ir.PEXTERN { // Tell liveness we're about to build a new slice s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, sn, s.mem()) } @@ -2909,8 +2909,8 @@ func (s *state) append(n *ir.Node, inplace bool) *ssa.Value { store bool } args := make([]argRec, 0, nargs) - for _, n := range n.List.Slice()[1:] { - if canSSAType(n.Type) { + for _, n := range n.List().Slice()[1:] { + if canSSAType(n.Type()) { args = append(args, argRec{v: s.expr(n), store: true}) } else { v := s.addr(n) @@ -2941,7 +2941,7 @@ func (s *state) append(n *ir.Node, inplace bool) *ssa.Value { delete(s.vars, newlenVar) delete(s.vars, capVar) // make result - return s.newValue3(ssa.OpSliceMake, n.Type, p, nl, c) + return s.newValue3(ssa.OpSliceMake, n.Type(), p, nl, c) } // condBranch evaluates the boolean expression cond and branches to yes @@ -2949,13 +2949,13 @@ func (s *state) append(n *ir.Node, inplace bool) *ssa.Value { // This function is intended to handle && and || better than just calling // s.expr(cond) and branching on the result. func (s *state) condBranch(cond *ir.Node, yes, no *ssa.Block, likely int8) { - switch cond.Op { + switch cond.Op() { case ir.OANDAND: mid := s.f.NewBlock(ssa.BlockPlain) - s.stmtList(cond.Ninit) - s.condBranch(cond.Left, mid, no, max8(likely, 0)) + s.stmtList(cond.Init()) + s.condBranch(cond.Left(), mid, no, max8(likely, 0)) s.startBlock(mid) - s.condBranch(cond.Right, yes, no, likely) + s.condBranch(cond.Right(), yes, no, likely) return // Note: if likely==1, then both recursive calls pass 1. // If likely==-1, then we don't have enough information to decide @@ -2965,17 +2965,17 @@ func (s *state) condBranch(cond *ir.Node, yes, no *ssa.Block, likely int8) { // OANDAND and OOROR nodes (if it ever has such info). case ir.OOROR: mid := s.f.NewBlock(ssa.BlockPlain) - s.stmtList(cond.Ninit) - s.condBranch(cond.Left, yes, mid, min8(likely, 0)) + s.stmtList(cond.Init()) + s.condBranch(cond.Left(), yes, mid, min8(likely, 0)) s.startBlock(mid) - s.condBranch(cond.Right, yes, no, likely) + s.condBranch(cond.Right(), yes, no, likely) return // Note: if likely==-1, then both recursive calls pass -1. // If likely==1, then we don't have enough info to decide // the likelihood of the first branch. case ir.ONOT: - s.stmtList(cond.Ninit) - s.condBranch(cond.Left, no, yes, -likely) + s.stmtList(cond.Init()) + s.condBranch(cond.Left(), no, yes, -likely) return } c := s.expr(cond) @@ -3001,16 +3001,16 @@ const ( // If deref is true and right == nil, just do left = 0. // skip indicates assignments (at the top level) that can be avoided. func (s *state) assign(left *ir.Node, right *ssa.Value, deref bool, skip skipMask) { - if left.Op == ir.ONAME && ir.IsBlank(left) { + if left.Op() == ir.ONAME && ir.IsBlank(left) { return } - t := left.Type + t := left.Type() dowidth(t) if s.canSSA(left) { if deref { s.Fatalf("can SSA LHS %v but not RHS %s", left, right) } - if left.Op == ir.ODOT { + if left.Op() == ir.ODOT { // We're assigning to a field of an ssa-able value. // We need to build a new structure with the new value for the // field we're assigning and the old values for the other fields. @@ -3021,12 +3021,12 @@ func (s *state) assign(left *ir.Node, right *ssa.Value, deref bool, skip skipMas // For the x.b = 5 assignment we want to generate x = T{x.a, 5, x.c} // Grab information about the structure type. - t := left.Left.Type + t := left.Left().Type() nf := t.NumFields() idx := fieldIdx(left) // Grab old value of structure. - old := s.expr(left.Left) + old := s.expr(left.Left()) // Make new structure. new := s.newValue0(ssa.StructMakeOp(t.NumFields()), t) @@ -3041,19 +3041,19 @@ func (s *state) assign(left *ir.Node, right *ssa.Value, deref bool, skip skipMas } // Recursively assign the new value we've made to the base of the dot op. - s.assign(left.Left, new, false, 0) + s.assign(left.Left(), new, false, 0) // TODO: do we need to update named values here? return } - if left.Op == ir.OINDEX && left.Left.Type.IsArray() { - s.pushLine(left.Pos) + if left.Op() == ir.OINDEX && left.Left().Type().IsArray() { + s.pushLine(left.Pos()) defer s.popLine() // We're assigning to an element of an ssa-able array. // a[i] = v - t := left.Left.Type + t := left.Left().Type() n := t.NumElem() - i := s.expr(left.Right) // index + i := s.expr(left.Right()) // index if n == 0 { // The bounds check must fail. Might as well // ignore the actual index and just use zeros. @@ -3068,7 +3068,7 @@ func (s *state) assign(left *ir.Node, right *ssa.Value, deref bool, skip skipMas len := s.constInt(types.Types[types.TINT], 1) s.boundsCheck(i, len, ssa.BoundsIndex, false) // checks i == 0 v := s.newValue1(ssa.OpArrayMake1, t, right) - s.assign(left.Left, v, false, 0) + s.assign(left.Left(), v, false, 0) return } // Update variable assignment. @@ -3079,7 +3079,7 @@ func (s *state) assign(left *ir.Node, right *ssa.Value, deref bool, skip skipMas // If this assignment clobbers an entire local variable, then emit // OpVarDef so liveness analysis knows the variable is redefined. - if base := clobberBase(left); base.Op == ir.ONAME && base.Class() != ir.PEXTERN && skip == 0 { + if base := clobberBase(left); base.Op() == ir.ONAME && base.Class() != ir.PEXTERN && skip == 0 { s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, base, s.mem(), !ir.IsAutoTmp(base)) } @@ -3323,7 +3323,7 @@ func init() { // Compiler frontend optimizations emit OBYTES2STRTMP nodes // for the backend instead of slicebytetostringtmp calls // when not instrumenting. - return s.newValue2(ssa.OpStringMake, n.Type, args[0], args[1]) + return s.newValue2(ssa.OpStringMake, n.Type(), args[0], args[1]) }, all...) } @@ -4157,15 +4157,15 @@ func findIntrinsic(sym *types.Sym) intrinsicBuilder { } func isIntrinsicCall(n *ir.Node) bool { - if n == nil || n.Left == nil { + if n == nil || n.Left() == nil { return false } - return findIntrinsic(n.Left.Sym) != nil + return findIntrinsic(n.Left().Sym()) != nil } // intrinsicCall converts a call to a recognized intrinsic function into the intrinsic SSA operation. func (s *state) intrinsicCall(n *ir.Node) *ssa.Value { - v := findIntrinsic(n.Left.Sym)(s, n, s.intrinsicArgs(n)) + v := findIntrinsic(n.Left().Sym())(s, n, s.intrinsicArgs(n)) if ssa.IntrinsicsDebug > 0 { x := v if x == nil { @@ -4174,7 +4174,7 @@ func (s *state) intrinsicCall(n *ir.Node) *ssa.Value { if x.Op == ssa.OpSelect0 || x.Op == ssa.OpSelect1 { x = x.Args[0] } - base.WarnfAt(n.Pos, "intrinsic substitution for %v with %s", n.Left.Sym.Name, x.LongString()) + base.WarnfAt(n.Pos(), "intrinsic substitution for %v with %s", n.Left().Sym().Name, x.LongString()) } return v } @@ -4183,20 +4183,20 @@ func (s *state) intrinsicCall(n *ir.Node) *ssa.Value { func (s *state) intrinsicArgs(n *ir.Node) []*ssa.Value { // Construct map of temps; see comments in s.call about the structure of n. temps := map[*ir.Node]*ssa.Value{} - for _, a := range n.List.Slice() { - if a.Op != ir.OAS { - s.Fatalf("non-assignment as a temp function argument %v", a.Op) + for _, a := range n.List().Slice() { + if a.Op() != ir.OAS { + s.Fatalf("non-assignment as a temp function argument %v", a.Op()) } - l, r := a.Left, a.Right - if l.Op != ir.ONAME { - s.Fatalf("non-ONAME temp function argument %v", a.Op) + l, r := a.Left(), a.Right() + if l.Op() != ir.ONAME { + s.Fatalf("non-ONAME temp function argument %v", a.Op()) } // Evaluate and store to "temporary". // Walk ensures these temporaries are dead outside of n. temps[l] = s.expr(r) } - args := make([]*ssa.Value, n.Rlist.Len()) - for i, n := range n.Rlist.Slice() { + args := make([]*ssa.Value, n.Rlist().Len()) + for i, n := range n.Rlist().Slice() { // Store a value to an argument slot. if x, ok := temps[n]; ok { // This is a previously computed temporary. @@ -4221,7 +4221,7 @@ func (s *state) openDeferRecord(n *ir.Node) { // once.mutex'. Such a statement will create a mapping in s.vars[] from // the autotmp name to the evaluated SSA arg value, but won't do any // stores to the stack. - s.stmtList(n.List) + s.stmtList(n.List()) var args []*ssa.Value var argNodes []*ir.Node @@ -4229,45 +4229,45 @@ func (s *state) openDeferRecord(n *ir.Node) { opendefer := &openDeferInfo{ n: n, } - fn := n.Left - if n.Op == ir.OCALLFUNC { + fn := n.Left() + if n.Op() == ir.OCALLFUNC { // We must always store the function value in a stack slot for the // runtime panic code to use. But in the defer exit code, we will // call the function directly if it is a static function. closureVal := s.expr(fn) - closure := s.openDeferSave(nil, fn.Type, closureVal) + closure := s.openDeferSave(nil, fn.Type(), closureVal) opendefer.closureNode = closure.Aux.(*ir.Node) - if !(fn.Op == ir.ONAME && fn.Class() == ir.PFUNC) { + if !(fn.Op() == ir.ONAME && fn.Class() == ir.PFUNC) { opendefer.closure = closure } - } else if n.Op == ir.OCALLMETH { - if fn.Op != ir.ODOTMETH { + } else if n.Op() == ir.OCALLMETH { + if fn.Op() != ir.ODOTMETH { base.Fatalf("OCALLMETH: n.Left not an ODOTMETH: %v", fn) } closureVal := s.getMethodClosure(fn) // We must always store the function value in a stack slot for the // runtime panic code to use. But in the defer exit code, we will // call the method directly. - closure := s.openDeferSave(nil, fn.Type, closureVal) + closure := s.openDeferSave(nil, fn.Type(), closureVal) opendefer.closureNode = closure.Aux.(*ir.Node) } else { - if fn.Op != ir.ODOTINTER { - base.Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op) + if fn.Op() != ir.ODOTINTER { + base.Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op()) } closure, rcvr := s.getClosureAndRcvr(fn) opendefer.closure = s.openDeferSave(nil, closure.Type, closure) // Important to get the receiver type correct, so it is recognized // as a pointer for GC purposes. - opendefer.rcvr = s.openDeferSave(nil, fn.Type.Recv().Type, rcvr) + opendefer.rcvr = s.openDeferSave(nil, fn.Type().Recv().Type, rcvr) opendefer.closureNode = opendefer.closure.Aux.(*ir.Node) opendefer.rcvrNode = opendefer.rcvr.Aux.(*ir.Node) } - for _, argn := range n.Rlist.Slice() { + for _, argn := range n.Rlist().Slice() { var v *ssa.Value - if canSSAType(argn.Type) { - v = s.openDeferSave(nil, argn.Type, s.expr(argn)) + if canSSAType(argn.Type()) { + v = s.openDeferSave(nil, argn.Type(), s.expr(argn)) } else { - v = s.openDeferSave(argn, argn.Type, nil) + v = s.openDeferSave(argn, argn.Type(), nil) } args = append(args, v) argNodes = append(argNodes, v.Aux.(*ir.Node)) @@ -4298,10 +4298,10 @@ func (s *state) openDeferSave(n *ir.Node, t *types.Type, val *ssa.Value) *ssa.Va if canSSA { pos = val.Pos } else { - pos = n.Pos + pos = n.Pos() } argTemp := tempAt(pos.WithNotStmt(), s.curfn, t) - argTemp.Name.SetOpenDeferSlot(true) + argTemp.Name().SetOpenDeferSlot(true) var addrArgTemp *ssa.Value // Use OpVarLive to make sure stack slots for the args, etc. are not // removed by dead-store elimination @@ -4312,14 +4312,14 @@ func (s *state) openDeferSave(n *ir.Node, t *types.Type, val *ssa.Value) *ssa.Va // associated defer call has been activated). s.defvars[s.f.Entry.ID][memVar] = s.entryNewValue1A(ssa.OpVarDef, types.TypeMem, argTemp, s.defvars[s.f.Entry.ID][memVar]) s.defvars[s.f.Entry.ID][memVar] = s.entryNewValue1A(ssa.OpVarLive, types.TypeMem, argTemp, s.defvars[s.f.Entry.ID][memVar]) - addrArgTemp = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(argTemp.Type), argTemp, s.sp, s.defvars[s.f.Entry.ID][memVar]) + addrArgTemp = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(argTemp.Type()), argTemp, s.sp, s.defvars[s.f.Entry.ID][memVar]) } else { // Special case if we're still in the entry block. We can't use // the above code, since s.defvars[s.f.Entry.ID] isn't defined // until we end the entry block with s.endBlock(). s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, argTemp, s.mem(), false) s.vars[memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, argTemp, s.mem(), false) - addrArgTemp = s.newValue2Apos(ssa.OpLocalAddr, types.NewPtr(argTemp.Type), argTemp, s.sp, s.mem(), false) + addrArgTemp = s.newValue2Apos(ssa.OpLocalAddr, types.NewPtr(argTemp.Type()), argTemp, s.sp, s.mem(), false) } if t.HasPointers() { // Since we may use this argTemp during exit depending on the @@ -4327,7 +4327,7 @@ func (s *state) openDeferSave(n *ir.Node, t *types.Type, val *ssa.Value) *ssa.Va // Therefore, we must make sure it is zeroed out in the entry // block if it contains pointers, else GC may wrongly follow an // uninitialized pointer value. - argTemp.Name.SetNeedzero(true) + argTemp.Name().SetNeedzero(true) } if !canSSA { a := s.addr(n) @@ -4385,8 +4385,8 @@ func (s *state) openDeferExit() { // closure/receiver/args that were stored in argtmps at the point // of the defer statement. argStart := base.Ctxt.FixedFrameSize() - fn := r.n.Left - stksize := fn.Type.ArgWidth() + fn := r.n.Left() + stksize := fn.Type().ArgWidth() var ACArgs []ssa.Param var ACResults []ssa.Param var callArgs []*ssa.Value @@ -4437,7 +4437,7 @@ func (s *state) openDeferExit() { call = s.newValue3A(ssa.OpClosureCall, types.TypeMem, aux, codeptr, v, s.mem()) } } else { - aux := ssa.StaticAuxCall(fn.Sym.Linksym(), ACArgs, ACResults) + aux := ssa.StaticAuxCall(fn.Sym().Linksym(), ACArgs, ACResults) if testLateExpansion { callArgs = append(callArgs, s.mem()) call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux) @@ -4461,12 +4461,12 @@ func (s *state) openDeferExit() { s.vars[memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, r.closureNode, s.mem(), false) } if r.rcvrNode != nil { - if r.rcvrNode.Type.HasPointers() { + if r.rcvrNode.Type().HasPointers() { s.vars[memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, r.rcvrNode, s.mem(), false) } } for _, argNode := range r.argNodes { - if argNode.Type.HasPointers() { + if argNode.Type().HasPointers() { s.vars[memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, argNode, s.mem(), false) } } @@ -4492,11 +4492,11 @@ func (s *state) call(n *ir.Node, k callKind, returnResultAddr bool) *ssa.Value { var closure *ssa.Value // ptr to closure to run (if dynamic) var codeptr *ssa.Value // ptr to target code (if dynamic) var rcvr *ssa.Value // receiver to set - fn := n.Left + fn := n.Left() var ACArgs []ssa.Param var ACResults []ssa.Param var callArgs []*ssa.Value - res := n.Left.Type.Results() + res := n.Left().Type().Results() if k == callNormal { nf := res.NumFields() for i := 0; i < nf; i++ { @@ -4507,11 +4507,11 @@ func (s *state) call(n *ir.Node, k callKind, returnResultAddr bool) *ssa.Value { testLateExpansion := false - switch n.Op { + switch n.Op() { case ir.OCALLFUNC: testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f) - if k == callNormal && fn.Op == ir.ONAME && fn.Class() == ir.PFUNC { - sym = fn.Sym + if k == callNormal && fn.Op() == ir.ONAME && fn.Class() == ir.PFUNC { + sym = fn.Sym() break } closure = s.expr(fn) @@ -4521,20 +4521,20 @@ func (s *state) call(n *ir.Node, k callKind, returnResultAddr bool) *ssa.Value { s.maybeNilCheckClosure(closure, k) } case ir.OCALLMETH: - if fn.Op != ir.ODOTMETH { + if fn.Op() != ir.ODOTMETH { s.Fatalf("OCALLMETH: n.Left not an ODOTMETH: %v", fn) } testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f) if k == callNormal { - sym = fn.Sym + sym = fn.Sym() break } closure = s.getMethodClosure(fn) // Note: receiver is already present in n.Rlist, so we don't // want to set it here. case ir.OCALLINTER: - if fn.Op != ir.ODOTINTER { - s.Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op) + if fn.Op() != ir.ODOTINTER { + s.Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op()) } testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f) var iclosure *ssa.Value @@ -4545,20 +4545,20 @@ func (s *state) call(n *ir.Node, k callKind, returnResultAddr bool) *ssa.Value { closure = iclosure } } - dowidth(fn.Type) - stksize := fn.Type.ArgWidth() // includes receiver, args, and results + dowidth(fn.Type()) + stksize := fn.Type().ArgWidth() // includes receiver, args, and results // Run all assignments of temps. // The temps are introduced to avoid overwriting argument // slots when arguments themselves require function calls. - s.stmtList(n.List) + s.stmtList(n.List()) var call *ssa.Value if k == callDeferStack { testLateExpansion = ssa.LateCallExpansionEnabledWithin(s.f) // Make a defer struct d on the stack. t := deferstruct(stksize) - d := tempAt(n.Pos, s.curfn, t) + d := tempAt(n.Pos(), s.curfn, t) s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, d, s.mem()) addr := s.addr(d) @@ -4584,9 +4584,9 @@ func (s *state) call(n *ir.Node, k callKind, returnResultAddr bool) *ssa.Value { // 11: fd // Then, store all the arguments of the defer call. - ft := fn.Type + ft := fn.Type() off := t.FieldOff(12) - args := n.Rlist.Slice() + args := n.Rlist().Slice() // Set receiver (for interface calls). Always a pointer. if rcvr != nil { @@ -4594,7 +4594,7 @@ func (s *state) call(n *ir.Node, k callKind, returnResultAddr bool) *ssa.Value { s.store(types.Types[types.TUINTPTR], p, rcvr) } // Set receiver (for method calls). - if n.Op == ir.OCALLMETH { + if n.Op() == ir.OCALLMETH { f := ft.Recv() s.storeArgWithBase(args[0], f.Type, addr, off+f.Offset) args = args[1:] @@ -4662,9 +4662,9 @@ func (s *state) call(n *ir.Node, k callKind, returnResultAddr bool) *ssa.Value { } // Write args. - t := n.Left.Type - args := n.Rlist.Slice() - if n.Op == ir.OCALLMETH { + t := n.Left().Type() + args := n.Rlist().Slice() + if n.Op() == ir.OCALLMETH { f := t.Recv() ACArg, arg := s.putArg(args[0], f.Type, argStart+f.Offset, testLateExpansion) ACArgs = append(ACArgs, ACArg) @@ -4729,7 +4729,7 @@ func (s *state) call(n *ir.Node, k callKind, returnResultAddr bool) *ssa.Value { call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, ssa.StaticAuxCall(sym.Linksym(), ACArgs, ACResults), s.mem()) } default: - s.Fatalf("bad call type %v %v", n.Op, n) + s.Fatalf("bad call type %v %v", n.Op(), n) } call.AuxInt = stksize // Call operations carry the argsize of the callee along with them } @@ -4740,7 +4740,7 @@ func (s *state) call(n *ir.Node, k callKind, returnResultAddr bool) *ssa.Value { s.vars[memVar] = call } // Insert OVARLIVE nodes - s.stmtList(n.Nbody) + s.stmtList(n.Body()) // Finish block for defers if k == callDefer || k == callDeferStack { @@ -4774,7 +4774,7 @@ func (s *state) call(n *ir.Node, k callKind, returnResultAddr bool) *ssa.Value { if testLateExpansion { return s.newValue1I(ssa.OpSelectN, fp.Type, 0, call) } - return s.load(n.Type, s.constOffPtrSP(types.NewPtr(fp.Type), fp.Offset+base.Ctxt.FixedFrameSize())) + return s.load(n.Type(), s.constOffPtrSP(types.NewPtr(fp.Type), fp.Offset+base.Ctxt.FixedFrameSize())) } // maybeNilCheckClosure checks if a nil check of a closure is needed in some @@ -4794,22 +4794,22 @@ func (s *state) getMethodClosure(fn *ir.Node) *ssa.Value { // Make a PFUNC node out of that, then evaluate it. // We get back an SSA value representing &sync.(*Mutex).Unlock·f. // We can then pass that to defer or go. - n2 := ir.NewNameAt(fn.Pos, fn.Sym) - n2.Name.Curfn = s.curfn + n2 := ir.NewNameAt(fn.Pos(), fn.Sym()) + n2.Name().Curfn = s.curfn n2.SetClass(ir.PFUNC) // n2.Sym already existed, so it's already marked as a function. - n2.Pos = fn.Pos - n2.Type = types.Types[types.TUINT8] // fake type for a static closure. Could use runtime.funcval if we had it. + n2.SetPos(fn.Pos()) + n2.SetType(types.Types[types.TUINT8]) // fake type for a static closure. Could use runtime.funcval if we had it. return s.expr(n2) } // getClosureAndRcvr returns values for the appropriate closure and receiver of an // interface call func (s *state) getClosureAndRcvr(fn *ir.Node) (*ssa.Value, *ssa.Value) { - i := s.expr(fn.Left) + i := s.expr(fn.Left()) itab := s.newValue1(ssa.OpITab, types.Types[types.TUINTPTR], i) s.nilCheck(itab) - itabidx := fn.Xoffset + 2*int64(Widthptr) + 8 // offset of fun field in runtime.itab + itabidx := fn.Offset() + 2*int64(Widthptr) + 8 // offset of fun field in runtime.itab closure := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.UintptrPtr, itabidx, itab) rcvr := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, i) return closure, rcvr @@ -4830,21 +4830,21 @@ func etypesign(e types.EType) int8 { // addr converts the address of the expression n to SSA, adds it to s and returns the SSA result. // The value that the returned Value represents is guaranteed to be non-nil. func (s *state) addr(n *ir.Node) *ssa.Value { - if n.Op != ir.ONAME { - s.pushLine(n.Pos) + if n.Op() != ir.ONAME { + s.pushLine(n.Pos()) defer s.popLine() } - t := types.NewPtr(n.Type) - switch n.Op { + t := types.NewPtr(n.Type()) + switch n.Op() { case ir.ONAME: switch n.Class() { case ir.PEXTERN: // global variable - v := s.entryNewValue1A(ssa.OpAddr, t, n.Sym.Linksym(), s.sb) + v := s.entryNewValue1A(ssa.OpAddr, t, n.Sym().Linksym(), s.sb) // TODO: Make OpAddr use AuxInt as well as Aux. - if n.Xoffset != 0 { - v = s.entryNewValue1I(ssa.OpOffPtr, v.Type, n.Xoffset, v) + if n.Offset() != 0 { + v = s.entryNewValue1I(ssa.OpOffPtr, v.Type, n.Offset(), v) } return v case ir.PPARAM: @@ -4873,44 +4873,44 @@ func (s *state) addr(n *ir.Node) *ssa.Value { case ir.ORESULT: // load return from callee if s.prevCall == nil || s.prevCall.Op != ssa.OpStaticLECall && s.prevCall.Op != ssa.OpInterLECall && s.prevCall.Op != ssa.OpClosureLECall { - return s.constOffPtrSP(t, n.Xoffset) + return s.constOffPtrSP(t, n.Offset()) } - which := s.prevCall.Aux.(*ssa.AuxCall).ResultForOffset(n.Xoffset) + which := s.prevCall.Aux.(*ssa.AuxCall).ResultForOffset(n.Offset()) if which == -1 { // Do the old thing // TODO: Panic instead. - return s.constOffPtrSP(t, n.Xoffset) + return s.constOffPtrSP(t, n.Offset()) } x := s.newValue1I(ssa.OpSelectNAddr, t, which, s.prevCall) return x case ir.OINDEX: - if n.Left.Type.IsSlice() { - a := s.expr(n.Left) - i := s.expr(n.Right) + if n.Left().Type().IsSlice() { + a := s.expr(n.Left()) + i := s.expr(n.Right()) len := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], a) i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded()) p := s.newValue1(ssa.OpSlicePtr, t, a) return s.newValue2(ssa.OpPtrIndex, t, p, i) } else { // array - a := s.addr(n.Left) - i := s.expr(n.Right) - len := s.constInt(types.Types[types.TINT], n.Left.Type.NumElem()) + a := s.addr(n.Left()) + i := s.expr(n.Right()) + len := s.constInt(types.Types[types.TINT], n.Left().Type().NumElem()) i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded()) - return s.newValue2(ssa.OpPtrIndex, types.NewPtr(n.Left.Type.Elem()), a, i) + return s.newValue2(ssa.OpPtrIndex, types.NewPtr(n.Left().Type().Elem()), a, i) } case ir.ODEREF: - return s.exprPtr(n.Left, n.Bounded(), n.Pos) + return s.exprPtr(n.Left(), n.Bounded(), n.Pos()) case ir.ODOT: - p := s.addr(n.Left) - return s.newValue1I(ssa.OpOffPtr, t, n.Xoffset, p) + p := s.addr(n.Left()) + return s.newValue1I(ssa.OpOffPtr, t, n.Offset(), p) case ir.ODOTPTR: - p := s.exprPtr(n.Left, n.Bounded(), n.Pos) - return s.newValue1I(ssa.OpOffPtr, t, n.Xoffset, p) + p := s.exprPtr(n.Left(), n.Bounded(), n.Pos()) + return s.newValue1I(ssa.OpOffPtr, t, n.Offset(), p) case ir.OCLOSUREVAR: - return s.newValue1I(ssa.OpOffPtr, t, n.Xoffset, + return s.newValue1I(ssa.OpOffPtr, t, n.Offset(), s.entryNewValue0(ssa.OpGetClosurePtr, s.f.Config.Types.BytePtr)) case ir.OCONVNOP: - addr := s.addr(n.Left) + addr := s.addr(n.Left()) return s.newValue1(ssa.OpCopy, t, addr) // ensure that addr has the right type case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH: return s.callAddr(n, callNormal) @@ -4924,7 +4924,7 @@ func (s *state) addr(n *ir.Node) *ssa.Value { } return v.Args[0] default: - s.Fatalf("unhandled addr %v", n.Op) + s.Fatalf("unhandled addr %v", n.Op()) return nil } } @@ -4935,13 +4935,13 @@ func (s *state) canSSA(n *ir.Node) bool { if base.Flag.N != 0 { return false } - for n.Op == ir.ODOT || (n.Op == ir.OINDEX && n.Left.Type.IsArray()) { - n = n.Left + for n.Op() == ir.ODOT || (n.Op() == ir.OINDEX && n.Left().Type().IsArray()) { + n = n.Left() } - if n.Op != ir.ONAME { + if n.Op() != ir.ONAME { return false } - if n.Name.Addrtaken() { + if n.Name().Addrtaken() { return false } if isParamHeapCopy(n) { @@ -4968,13 +4968,13 @@ func (s *state) canSSA(n *ir.Node) bool { return false } } - if n.Class() == ir.PPARAM && n.Sym != nil && n.Sym.Name == ".this" { + if n.Class() == ir.PPARAM && n.Sym() != nil && n.Sym().Name == ".this" { // wrappers generated by genwrapper need to update // the .this pointer in place. // TODO: treat as a PPARAMOUT? return false } - return canSSAType(n.Type) + return canSSAType(n.Type()) // TODO: try to make more variables SSAable? } @@ -5028,7 +5028,7 @@ func (s *state) exprPtr(n *ir.Node, bounded bool, lineno src.XPos) *ssa.Value { // Used only for automatically inserted nil checks, // not for user code like 'x != nil'. func (s *state) nilCheck(ptr *ssa.Value) { - if base.Debug.DisableNil != 0 || s.curfn.Func.NilCheckDisabled() { + if base.Debug.DisableNil != 0 || s.curfn.Func().NilCheckDisabled() { return } s.newValue2(ssa.OpNilCheck, types.TypeVoid, ptr, s.mem()) @@ -5161,10 +5161,10 @@ func (s *state) intDivide(n *ir.Node, a, b *ssa.Value) *ssa.Value { } if needcheck { // do a size-appropriate check for zero - cmp := s.newValue2(s.ssaOp(ir.ONE, n.Type), types.Types[types.TBOOL], b, s.zeroVal(n.Type)) + cmp := s.newValue2(s.ssaOp(ir.ONE, n.Type()), types.Types[types.TBOOL], b, s.zeroVal(n.Type())) s.check(cmp, panicdivide) } - return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b) + return s.newValue2(s.ssaOp(n.Op(), n.Type()), a.Type, a, b) } // rtcall issues a call to the given runtime function fn with the listed args. @@ -5609,7 +5609,7 @@ func (s *state) uint64Tofloat(cvttab *u642fcvtTab, n *ir.Node, x *ssa.Value, ft, bElse.AddEdgeTo(bAfter) s.startBlock(bAfter) - return s.variable(n, n.Type) + return s.variable(n, n.Type()) } type u322fcvtTab struct { @@ -5669,12 +5669,12 @@ func (s *state) uint32Tofloat(cvttab *u322fcvtTab, n *ir.Node, x *ssa.Value, ft, bElse.AddEdgeTo(bAfter) s.startBlock(bAfter) - return s.variable(n, n.Type) + return s.variable(n, n.Type()) } // referenceTypeBuiltin generates code for the len/cap builtins for maps and channels. func (s *state) referenceTypeBuiltin(n *ir.Node, x *ssa.Value) *ssa.Value { - if !n.Left.Type.IsMap() && !n.Left.Type.IsChan() { + if !n.Left().Type().IsMap() && !n.Left().Type().IsChan() { s.Fatalf("node must be a map or a channel") } // if n == nil { @@ -5685,7 +5685,7 @@ func (s *state) referenceTypeBuiltin(n *ir.Node, x *ssa.Value) *ssa.Value { // // cap // return *(((*int)n)+1) // } - lenType := n.Type + lenType := n.Type() nilValue := s.constNil(types.Types[types.TUINTPTR]) cmp := s.newValue2(ssa.OpEqPtr, types.Types[types.TBOOL], x, nilValue) b := s.endBlock() @@ -5706,7 +5706,7 @@ func (s *state) referenceTypeBuiltin(n *ir.Node, x *ssa.Value) *ssa.Value { b.AddEdgeTo(bElse) s.startBlock(bElse) - switch n.Op { + switch n.Op() { case ir.OLEN: // length is stored in the first word for map/chan s.vars[n] = s.load(lenType, x) @@ -5824,23 +5824,23 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n *ir.Node, x *ssa.Value, ft, tt bElse.AddEdgeTo(bAfter) s.startBlock(bAfter) - return s.variable(n, n.Type) + return s.variable(n, n.Type()) } // dottype generates SSA for a type assertion node. // commaok indicates whether to panic or return a bool. // If commaok is false, resok will be nil. func (s *state) dottype(n *ir.Node, commaok bool) (res, resok *ssa.Value) { - iface := s.expr(n.Left) // input interface - target := s.expr(n.Right) // target type + iface := s.expr(n.Left()) // input interface + target := s.expr(n.Right()) // target type byteptr := s.f.Config.Types.BytePtr - if n.Type.IsInterface() { - if n.Type.IsEmptyInterface() { + if n.Type().IsInterface() { + if n.Type().IsEmptyInterface() { // Converting to an empty interface. // Input could be an empty or nonempty interface. if base.Debug.TypeAssert > 0 { - base.WarnfAt(n.Pos, "type assertion inlined") + base.WarnfAt(n.Pos(), "type assertion inlined") } // Get itab/type field from input. @@ -5848,7 +5848,7 @@ func (s *state) dottype(n *ir.Node, commaok bool) (res, resok *ssa.Value) { // Conversion succeeds iff that field is not nil. cond := s.newValue2(ssa.OpNeqPtr, types.Types[types.TBOOL], itab, s.constNil(byteptr)) - if n.Left.Type.IsEmptyInterface() && commaok { + if n.Left().Type().IsEmptyInterface() && commaok { // Converting empty interface to empty interface with ,ok is just a nil check. return iface, cond } @@ -5870,15 +5870,15 @@ func (s *state) dottype(n *ir.Node, commaok bool) (res, resok *ssa.Value) { // On success, return (perhaps modified) input interface. s.startBlock(bOk) - if n.Left.Type.IsEmptyInterface() { + if n.Left().Type().IsEmptyInterface() { res = iface // Use input interface unchanged. return } // Load type out of itab, build interface with existing idata. off := s.newValue1I(ssa.OpOffPtr, byteptr, int64(Widthptr), itab) typ := s.load(byteptr, off) - idata := s.newValue1(ssa.OpIData, n.Type, iface) - res = s.newValue2(ssa.OpIMake, n.Type, typ, idata) + idata := s.newValue1(ssa.OpIData, n.Type(), iface) + res = s.newValue2(ssa.OpIMake, n.Type(), typ, idata) return } @@ -5899,55 +5899,55 @@ func (s *state) dottype(n *ir.Node, commaok bool) (res, resok *ssa.Value) { bOk.AddEdgeTo(bEnd) bFail.AddEdgeTo(bEnd) s.startBlock(bEnd) - idata := s.newValue1(ssa.OpIData, n.Type, iface) - res = s.newValue2(ssa.OpIMake, n.Type, s.variable(typVar, byteptr), idata) + idata := s.newValue1(ssa.OpIData, n.Type(), iface) + res = s.newValue2(ssa.OpIMake, n.Type(), s.variable(typVar, byteptr), idata) resok = cond delete(s.vars, typVar) return } // converting to a nonempty interface needs a runtime call. if base.Debug.TypeAssert > 0 { - base.WarnfAt(n.Pos, "type assertion not inlined") + base.WarnfAt(n.Pos(), "type assertion not inlined") } - if n.Left.Type.IsEmptyInterface() { + if n.Left().Type().IsEmptyInterface() { if commaok { - call := s.rtcall(assertE2I2, true, []*types.Type{n.Type, types.Types[types.TBOOL]}, target, iface) + call := s.rtcall(assertE2I2, true, []*types.Type{n.Type(), types.Types[types.TBOOL]}, target, iface) return call[0], call[1] } - return s.rtcall(assertE2I, true, []*types.Type{n.Type}, target, iface)[0], nil + return s.rtcall(assertE2I, true, []*types.Type{n.Type()}, target, iface)[0], nil } if commaok { - call := s.rtcall(assertI2I2, true, []*types.Type{n.Type, types.Types[types.TBOOL]}, target, iface) + call := s.rtcall(assertI2I2, true, []*types.Type{n.Type(), types.Types[types.TBOOL]}, target, iface) return call[0], call[1] } - return s.rtcall(assertI2I, true, []*types.Type{n.Type}, target, iface)[0], nil + return s.rtcall(assertI2I, true, []*types.Type{n.Type()}, target, iface)[0], nil } if base.Debug.TypeAssert > 0 { - base.WarnfAt(n.Pos, "type assertion inlined") + base.WarnfAt(n.Pos(), "type assertion inlined") } // Converting to a concrete type. - direct := isdirectiface(n.Type) + direct := isdirectiface(n.Type()) itab := s.newValue1(ssa.OpITab, byteptr, iface) // type word of interface if base.Debug.TypeAssert > 0 { - base.WarnfAt(n.Pos, "type assertion inlined") + base.WarnfAt(n.Pos(), "type assertion inlined") } var targetITab *ssa.Value - if n.Left.Type.IsEmptyInterface() { + if n.Left().Type().IsEmptyInterface() { // Looking for pointer to target type. targetITab = target } else { // Looking for pointer to itab for target type and source interface. - targetITab = s.expr(n.List.First()) + targetITab = s.expr(n.List().First()) } var tmp *ir.Node // temporary for use with large types var addr *ssa.Value // address of tmp - if commaok && !canSSAType(n.Type) { + if commaok && !canSSAType(n.Type()) { // unSSAable type, use temporary. // TODO: get rid of some of these temporaries. - tmp = tempAt(n.Pos, s.curfn, n.Type) + tmp = tempAt(n.Pos(), s.curfn, n.Type()) s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, tmp, s.mem()) addr = s.addr(tmp) } @@ -5966,8 +5966,8 @@ func (s *state) dottype(n *ir.Node, commaok bool) (res, resok *ssa.Value) { if !commaok { // on failure, panic by calling panicdottype s.startBlock(bFail) - taddr := s.expr(n.Right.Right) - if n.Left.Type.IsEmptyInterface() { + taddr := s.expr(n.Right().Right()) + if n.Left().Type().IsEmptyInterface() { s.rtcall(panicdottypeE, false, nil, itab, target, taddr) } else { s.rtcall(panicdottypeI, false, nil, itab, target, taddr) @@ -5976,10 +5976,10 @@ func (s *state) dottype(n *ir.Node, commaok bool) (res, resok *ssa.Value) { // on success, return data from interface s.startBlock(bOk) if direct { - return s.newValue1(ssa.OpIData, n.Type, iface), nil + return s.newValue1(ssa.OpIData, n.Type(), iface), nil } - p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type), iface) - return s.load(n.Type, p), nil + p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type()), iface) + return s.load(n.Type(), p), nil } // commaok is the more complicated case because we have @@ -5993,14 +5993,14 @@ func (s *state) dottype(n *ir.Node, commaok bool) (res, resok *ssa.Value) { s.startBlock(bOk) if tmp == nil { if direct { - s.vars[valVar] = s.newValue1(ssa.OpIData, n.Type, iface) + s.vars[valVar] = s.newValue1(ssa.OpIData, n.Type(), iface) } else { - p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type), iface) - s.vars[valVar] = s.load(n.Type, p) + p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type()), iface) + s.vars[valVar] = s.load(n.Type(), p) } } else { - p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type), iface) - s.move(n.Type, addr, p) + p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type()), iface) + s.move(n.Type(), addr, p) } s.vars[okVar] = s.constBool(true) s.endBlock() @@ -6009,9 +6009,9 @@ func (s *state) dottype(n *ir.Node, commaok bool) (res, resok *ssa.Value) { // type assertion failed s.startBlock(bFail) if tmp == nil { - s.vars[valVar] = s.zeroVal(n.Type) + s.vars[valVar] = s.zeroVal(n.Type()) } else { - s.zero(n.Type, addr) + s.zero(n.Type(), addr) } s.vars[okVar] = s.constBool(false) s.endBlock() @@ -6020,10 +6020,10 @@ func (s *state) dottype(n *ir.Node, commaok bool) (res, resok *ssa.Value) { // merge point s.startBlock(bEnd) if tmp == nil { - res = s.variable(valVar, n.Type) + res = s.variable(valVar, n.Type()) delete(s.vars, valVar) } else { - res = s.load(n.Type, addr) + res = s.load(n.Type(), addr) s.vars[memVar] = s.newValue1A(ssa.OpVarKill, types.TypeMem, tmp, s.mem()) } resok = s.variable(okVar, types.Types[types.TBOOL]) @@ -6072,10 +6072,10 @@ func (s *state) addNamedValue(n *ir.Node, v *ssa.Value) { // from being assigned too early. See #14591 and #14762. TODO: allow this. return } - if n.Class() == ir.PAUTO && n.Xoffset != 0 { - s.Fatalf("AUTO var with offset %v %d", n, n.Xoffset) + if n.Class() == ir.PAUTO && n.Offset() != 0 { + s.Fatalf("AUTO var with offset %v %d", n, n.Offset()) } - loc := ssa.LocalSlot{N: n, Type: n.Type, Off: 0} + loc := ssa.LocalSlot{N: n, Type: n.Type(), Off: 0} values, ok := s.f.NamedValues[loc] if !ok { s.f.Names = append(s.f.Names, loc) @@ -6197,13 +6197,13 @@ func (s *SSAGenState) DebugFriendlySetPosFrom(v *ssa.Value) { type byXoffset []*ir.Node func (s byXoffset) Len() int { return len(s) } -func (s byXoffset) Less(i, j int) bool { return s[i].Xoffset < s[j].Xoffset } +func (s byXoffset) Less(i, j int) bool { return s[i].Offset() < s[j].Offset() } func (s byXoffset) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func emitStackObjects(e *ssafn, pp *Progs) { var vars []*ir.Node - for _, n := range e.curfn.Func.Dcl { - if livenessShouldTrack(n) && n.Name.Addrtaken() { + for _, n := range e.curfn.Func().Dcl { + if livenessShouldTrack(n) && n.Name().Addrtaken() { vars = append(vars, n) } } @@ -6216,18 +6216,18 @@ func emitStackObjects(e *ssafn, pp *Progs) { // Populate the stack object data. // Format must match runtime/stack.go:stackObjectRecord. - x := e.curfn.Func.LSym.Func().StackObjects + x := e.curfn.Func().LSym.Func().StackObjects off := 0 off = duintptr(x, off, uint64(len(vars))) for _, v := range vars { // Note: arguments and return values have non-negative Xoffset, // in which case the offset is relative to argp. // Locals have a negative Xoffset, in which case the offset is relative to varp. - off = duintptr(x, off, uint64(v.Xoffset)) - if !typesym(v.Type).Siggen() { - e.Fatalf(v.Pos, "stack object's type symbol not generated for type %s", v.Type) + off = duintptr(x, off, uint64(v.Offset())) + if !typesym(v.Type()).Siggen() { + e.Fatalf(v.Pos(), "stack object's type symbol not generated for type %s", v.Type()) } - off = dsymptr(x, off, dtypesym(v.Type), 0) + off = dsymptr(x, off, dtypesym(v.Type()), 0) } // Emit a funcdata pointing at the stack object data. @@ -6239,7 +6239,7 @@ func emitStackObjects(e *ssafn, pp *Progs) { if base.Flag.Live != 0 { for _, v := range vars { - base.WarnfAt(v.Pos, "stack object %v %s", v, v.Type.String()) + base.WarnfAt(v.Pos(), "stack object %v %s", v, v.Type().String()) } } } @@ -6253,7 +6253,7 @@ func genssa(f *ssa.Func, pp *Progs) { s.livenessMap = liveness(e, f, pp) emitStackObjects(e, pp) - openDeferInfo := e.curfn.Func.LSym.Func().OpenCodedDeferInfo + openDeferInfo := e.curfn.Func().LSym.Func().OpenCodedDeferInfo if openDeferInfo != nil { // This function uses open-coded defers -- write out the funcdata // info that we computed at the end of genssa. @@ -6458,7 +6458,7 @@ func genssa(f *ssa.Func, pp *Progs) { // some of the inline marks. // Use this instruction instead. p.Pos = p.Pos.WithIsStmt() // promote position to a statement - pp.curfn.Func.LSym.Func().AddInlMark(p, inlMarks[m]) + pp.curfn.Func().LSym.Func().AddInlMark(p, inlMarks[m]) // Make the inline mark a real nop, so it doesn't generate any code. m.As = obj.ANOP m.Pos = src.NoXPos @@ -6470,14 +6470,14 @@ func genssa(f *ssa.Func, pp *Progs) { // Any unmatched inline marks now need to be added to the inlining tree (and will generate a nop instruction). for _, p := range inlMarkList { if p.As != obj.ANOP { - pp.curfn.Func.LSym.Func().AddInlMark(p, inlMarks[p]) + pp.curfn.Func().LSym.Func().AddInlMark(p, inlMarks[p]) } } } if base.Ctxt.Flag_locationlists { debugInfo := ssa.BuildFuncDebug(base.Ctxt, f, base.Debug.LocationLists > 1, stackOffset) - e.curfn.Func.DebugInfo = debugInfo + e.curfn.Func().DebugInfo = debugInfo bstart := s.bstart // Note that at this moment, Prog.Pc is a sequence number; it's // not a real PC until after assembly, so this mapping has to @@ -6491,7 +6491,7 @@ func genssa(f *ssa.Func, pp *Progs) { } return bstart[b].Pc case ssa.BlockEnd.ID: - return e.curfn.Func.LSym.Size + return e.curfn.Func().LSym.Size default: return valueToProgAfter[v].Pc } @@ -6575,7 +6575,7 @@ func defframe(s *SSAGenState, e *ssafn) { // Fill in argument and frame size. pp.Text.To.Type = obj.TYPE_TEXTSIZE - pp.Text.To.Val = int32(Rnd(e.curfn.Type.ArgWidth(), int64(Widthreg))) + pp.Text.To.Val = int32(Rnd(e.curfn.Type().ArgWidth(), int64(Widthreg))) pp.Text.To.Offset = frame // Insert code to zero ambiguously live variables so that the @@ -6589,20 +6589,20 @@ func defframe(s *SSAGenState, e *ssafn) { var state uint32 // Iterate through declarations. They are sorted in decreasing Xoffset order. - for _, n := range e.curfn.Func.Dcl { - if !n.Name.Needzero() { + for _, n := range e.curfn.Func().Dcl { + if !n.Name().Needzero() { continue } if n.Class() != ir.PAUTO { - e.Fatalf(n.Pos, "needzero class %d", n.Class()) + e.Fatalf(n.Pos(), "needzero class %d", n.Class()) } - if n.Type.Size()%int64(Widthptr) != 0 || n.Xoffset%int64(Widthptr) != 0 || n.Type.Size() == 0 { - e.Fatalf(n.Pos, "var %L has size %d offset %d", n, n.Type.Size(), n.Xoffset) + if n.Type().Size()%int64(Widthptr) != 0 || n.Offset()%int64(Widthptr) != 0 || n.Type().Size() == 0 { + e.Fatalf(n.Pos(), "var %L has size %d offset %d", n, n.Type().Size(), n.Offset()) } - if lo != hi && n.Xoffset+n.Type.Size() >= lo-int64(2*Widthreg) { + if lo != hi && n.Offset()+n.Type().Size() >= lo-int64(2*Widthreg) { // Merge with range we already have. - lo = n.Xoffset + lo = n.Offset() continue } @@ -6610,8 +6610,8 @@ func defframe(s *SSAGenState, e *ssafn) { p = thearch.ZeroRange(pp, p, frame+lo, hi-lo, &state) // Set new range. - lo = n.Xoffset - hi = lo + n.Type.Size() + lo = n.Offset() + hi = lo + n.Type().Size() } // Zero final range. @@ -6680,13 +6680,13 @@ func AddAux2(a *obj.Addr, v *ssa.Value, offset int64) { case *ir.Node: if n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT { a.Name = obj.NAME_PARAM - a.Sym = n.Orig.Sym.Linksym() - a.Offset += n.Xoffset + a.Sym = n.Orig().Sym().Linksym() + a.Offset += n.Offset() break } a.Name = obj.NAME_AUTO - a.Sym = n.Sym.Linksym() - a.Offset += n.Xoffset + a.Sym = n.Sym().Linksym() + a.Offset += n.Offset() default: v.Fatalf("aux in %s not implemented %#v", v, v.Aux) } @@ -6827,9 +6827,9 @@ func AutoVar(v *ssa.Value) (*ir.Node, int64) { func AddrAuto(a *obj.Addr, v *ssa.Value) { n, off := AutoVar(v) a.Type = obj.TYPE_MEM - a.Sym = n.Sym.Linksym() + a.Sym = n.Sym().Linksym() a.Reg = int16(thearch.REGSP) - a.Offset = n.Xoffset + off + a.Offset = n.Offset() + off if n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT { a.Name = obj.NAME_PARAM } else { @@ -6843,9 +6843,9 @@ func (s *SSAGenState) AddrScratch(a *obj.Addr) { } a.Type = obj.TYPE_MEM a.Name = obj.NAME_AUTO - a.Sym = s.ScratchFpMem.Sym.Linksym() + a.Sym = s.ScratchFpMem.Sym().Linksym() a.Reg = int16(thearch.REGSP) - a.Offset = s.ScratchFpMem.Xoffset + a.Offset = s.ScratchFpMem.Offset() } // Call returns a new CALL instruction for the SSA value v. @@ -6928,8 +6928,8 @@ func (s *SSAGenState) UseArgs(n int64) { // fieldIdx finds the index of the field referred to by the ODOT node n. func fieldIdx(n *ir.Node) int { - t := n.Left.Type - f := n.Sym + t := n.Left().Type() + f := n.Sym() if !t.IsStruct() { panic("ODOT's LHS is not a struct") } @@ -6940,7 +6940,7 @@ func fieldIdx(n *ir.Node) int { i++ continue } - if t1.Offset != n.Xoffset { + if t1.Offset != n.Offset() { panic("field offset doesn't match") } return i @@ -6971,7 +6971,7 @@ func (e *ssafn) StringData(s string) *obj.LSym { if e.strings == nil { e.strings = make(map[string]*obj.LSym) } - data := stringsym(e.curfn.Pos, s) + data := stringsym(e.curfn.Pos(), s) e.strings[s] = data return data } @@ -6996,7 +6996,7 @@ func (e *ssafn) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot t := types.NewPtr(types.Types[types.TUINT8]) // Split this interface up into two separate variables. f := ".itab" - if n.Type.IsEmptyInterface() { + if n.Type().IsEmptyInterface() { f = ".type" } c := e.SplitSlot(&name, f, 0, u) // see comment in plive.go:onebitwalktype1. @@ -7051,7 +7051,7 @@ func (e *ssafn) SplitArray(name ssa.LocalSlot) ssa.LocalSlot { n := name.N at := name.Type if at.NumElem() != 1 { - e.Fatalf(n.Pos, "bad array size") + e.Fatalf(n.Pos(), "bad array size") } et := at.Elem() return e.SplitSlot(&name, "[0]", 0, et) @@ -7065,20 +7065,20 @@ func (e *ssafn) DerefItab(it *obj.LSym, offset int64) *obj.LSym { func (e *ssafn) SplitSlot(parent *ssa.LocalSlot, suffix string, offset int64, t *types.Type) ssa.LocalSlot { node := parent.N - if node.Class() != ir.PAUTO || node.Name.Addrtaken() { + if node.Class() != ir.PAUTO || node.Name().Addrtaken() { // addressed things and non-autos retain their parents (i.e., cannot truly be split) return ssa.LocalSlot{N: node, Type: t, Off: parent.Off + offset} } - s := &types.Sym{Name: node.Sym.Name + suffix, Pkg: ir.LocalPkg} - n := ir.NewNameAt(parent.N.Pos, s) + s := &types.Sym{Name: node.Sym().Name + suffix, Pkg: ir.LocalPkg} + n := ir.NewNameAt(parent.N.Pos(), s) s.Def = ir.AsTypesNode(n) - ir.AsNode(s.Def).Name.SetUsed(true) - n.Type = t + ir.AsNode(s.Def).Name().SetUsed(true) + n.SetType(t) n.SetClass(ir.PAUTO) - n.Esc = EscNever - n.Name.Curfn = e.curfn - e.curfn.Func.Dcl = append(e.curfn.Func.Dcl, n) + n.SetEsc(EscNever) + n.Name().Curfn = e.curfn + e.curfn.Func().Dcl = append(e.curfn.Func().Dcl, n) dowidth(t) return ssa.LocalSlot{N: n, Type: t, Off: 0, SplitOf: parent, SplitOffset: offset} } @@ -7141,7 +7141,7 @@ func (e *ssafn) Syslook(name string) *obj.LSym { } func (e *ssafn) SetWBPos(pos src.XPos) { - e.curfn.Func.SetWBPos(pos) + e.curfn.Func().SetWBPos(pos) } func (e *ssafn) MyImportPath() string { @@ -7149,11 +7149,11 @@ func (e *ssafn) MyImportPath() string { } func clobberBase(n *ir.Node) *ir.Node { - if n.Op == ir.ODOT && n.Left.Type.NumFields() == 1 { - return clobberBase(n.Left) + if n.Op() == ir.ODOT && n.Left().Type().NumFields() == 1 { + return clobberBase(n.Left()) } - if n.Op == ir.OINDEX && n.Left.Type.IsArray() && n.Left.Type.NumElem() == 1 { - return clobberBase(n.Left) + if n.Op() == ir.OINDEX && n.Left().Type().IsArray() && n.Left().Type().NumElem() == 1 { + return clobberBase(n.Left()) } return n } diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go index 46f4153fe1..542dc49bb0 100644 --- a/src/cmd/compile/internal/gc/subr.go +++ b/src/cmd/compile/internal/gc/subr.go @@ -41,16 +41,16 @@ var ( // whose Pos will point back to their declaration position rather than // their usage position. func hasUniquePos(n *ir.Node) bool { - switch n.Op { + switch n.Op() { case ir.ONAME, ir.OPACK: return false case ir.OLITERAL, ir.ONIL, ir.OTYPE: - if n.Sym != nil { + if n.Sym() != nil { return false } } - if !n.Pos.IsKnown() { + if !n.Pos().IsKnown() { if base.Flag.K != 0 { base.Warn("setlineno: unknown position (line 0)") } @@ -63,7 +63,7 @@ func hasUniquePos(n *ir.Node) bool { func setlineno(n *ir.Node) src.XPos { lno := base.Pos if n != nil && hasUniquePos(n) { - base.Pos = n.Pos + base.Pos = n.Pos() } return lno } @@ -95,8 +95,8 @@ func autolabel(prefix string) *types.Sym { if Curfn == nil { base.Fatalf("autolabel outside function") } - n := fn.Func.Label - fn.Func.Label++ + n := fn.Func().Label + fn.Func().Label++ return lookupN(prefix, int(n)) } @@ -120,25 +120,25 @@ func importdot(opkg *types.Pkg, pack *ir.Node) { s1.Def = s.Def s1.Block = s.Block - if ir.AsNode(s1.Def).Name == nil { + if ir.AsNode(s1.Def).Name() == nil { ir.Dump("s1def", ir.AsNode(s1.Def)) base.Fatalf("missing Name") } - ir.AsNode(s1.Def).Name.Pack = pack + ir.AsNode(s1.Def).Name().Pack = pack s1.Origpkg = opkg n++ } if n == 0 { // can't possibly be used - there were no symbols - base.ErrorfAt(pack.Pos, "imported and not used: %q", opkg.Path) + base.ErrorfAt(pack.Pos(), "imported and not used: %q", opkg.Path) } } // newname returns a new ONAME Node associated with symbol s. func NewName(s *types.Sym) *ir.Node { n := ir.NewNameAt(base.Pos, s) - n.Name.Curfn = Curfn + n.Name().Curfn = Curfn return n } @@ -152,7 +152,7 @@ func nodSym(op ir.Op, left *ir.Node, sym *types.Sym) *ir.Node { // and the Sym field set to sym. This is for ODOT and friends. func nodlSym(pos src.XPos, op ir.Op, left *ir.Node, sym *types.Sym) *ir.Node { n := ir.NodAt(pos, op, left, nil) - n.Sym = sym + n.SetSym(sym) return n } @@ -169,7 +169,7 @@ func nodintconst(v int64) *ir.Node { func nodnil() *ir.Node { n := ir.Nod(ir.ONIL, nil, nil) - n.Type = types.Types[types.TNIL] + n.SetType(types.Types[types.TNIL]) return n } @@ -190,16 +190,16 @@ func treecopy(n *ir.Node, pos src.XPos) *ir.Node { return nil } - switch n.Op { + switch n.Op() { default: m := ir.SepCopy(n) - m.Left = treecopy(n.Left, pos) - m.Right = treecopy(n.Right, pos) - m.List.Set(listtreecopy(n.List.Slice(), pos)) + m.SetLeft(treecopy(n.Left(), pos)) + m.SetRight(treecopy(n.Right(), pos)) + m.PtrList().Set(listtreecopy(n.List().Slice(), pos)) if pos.IsKnown() { - m.Pos = pos + m.SetPos(pos) } - if m.Name != nil && n.Op != ir.ODCLFIELD { + if m.Name() != nil && n.Op() != ir.ODCLFIELD { ir.Dump("treecopy", n) base.Fatalf("treecopy Name") } @@ -517,16 +517,16 @@ func assignconv(n *ir.Node, t *types.Type, context string) *ir.Node { // Convert node n for assignment to type t. func assignconvfn(n *ir.Node, t *types.Type, context func() string) *ir.Node { - if n == nil || n.Type == nil || n.Type.Broke() { + if n == nil || n.Type() == nil || n.Type().Broke() { return n } - if t.Etype == types.TBLANK && n.Type.Etype == types.TNIL { + if t.Etype == types.TBLANK && n.Type().Etype == types.TNIL { base.Errorf("use of untyped nil") } n = convlit1(n, t, false, context) - if n.Type == nil { + if n.Type() == nil { return n } if t.Etype == types.TBLANK { @@ -535,31 +535,31 @@ func assignconvfn(n *ir.Node, t *types.Type, context func() string) *ir.Node { // Convert ideal bool from comparison to plain bool // if the next step is non-bool (like interface{}). - if n.Type == types.UntypedBool && !t.IsBoolean() { - if n.Op == ir.ONAME || n.Op == ir.OLITERAL { + if n.Type() == types.UntypedBool && !t.IsBoolean() { + if n.Op() == ir.ONAME || n.Op() == ir.OLITERAL { r := ir.Nod(ir.OCONVNOP, n, nil) - r.Type = types.Types[types.TBOOL] + r.SetType(types.Types[types.TBOOL]) r.SetTypecheck(1) r.SetImplicit(true) n = r } } - if types.Identical(n.Type, t) { + if types.Identical(n.Type(), t) { return n } - op, why := assignop(n.Type, t) + op, why := assignop(n.Type(), t) if op == ir.OXXX { base.Errorf("cannot use %L as type %v in %s%s", n, t, context(), why) op = ir.OCONV } r := ir.Nod(op, n, nil) - r.Type = t + r.SetType(t) r.SetTypecheck(1) r.SetImplicit(true) - r.Orig = n.Orig + r.SetOrig(n.Orig()) return r } @@ -572,27 +572,27 @@ func backingArrayPtrLen(n *ir.Node) (ptr, len *ir.Node) { base.Fatalf("backingArrayPtrLen not cheap: %v", n) } ptr = ir.Nod(ir.OSPTR, n, nil) - if n.Type.IsString() { - ptr.Type = types.Types[types.TUINT8].PtrTo() + if n.Type().IsString() { + ptr.SetType(types.Types[types.TUINT8].PtrTo()) } else { - ptr.Type = n.Type.Elem().PtrTo() + ptr.SetType(n.Type().Elem().PtrTo()) } len = ir.Nod(ir.OLEN, n, nil) - len.Type = types.Types[types.TINT] + len.SetType(types.Types[types.TINT]) return ptr, len } // labeledControl returns the control flow Node (for, switch, select) // associated with the label n, if any. func labeledControl(n *ir.Node) *ir.Node { - if n.Op != ir.OLABEL { - base.Fatalf("labeledControl %v", n.Op) + if n.Op() != ir.OLABEL { + base.Fatalf("labeledControl %v", n.Op()) } - ctl := n.Name.Defn + ctl := n.Name().Defn if ctl == nil { return nil } - switch ctl.Op { + switch ctl.Op() { case ir.OFOR, ir.OFORUNTIL, ir.OSWITCH, ir.OSELECT: return ctl } @@ -626,12 +626,12 @@ func updateHasCall(n *ir.Node) { } func calcHasCall(n *ir.Node) bool { - if n.Ninit.Len() != 0 { + if n.Init().Len() != 0 { // TODO(mdempsky): This seems overly conservative. return true } - switch n.Op { + switch n.Op() { case ir.OLITERAL, ir.ONIL, ir.ONAME, ir.OTYPE: if n.HasCall() { base.Fatalf("OLITERAL/ONAME/OTYPE should never have calls: %+v", n) @@ -653,23 +653,23 @@ func calcHasCall(n *ir.Node) bool { // When using soft-float, these ops might be rewritten to function calls // so we ensure they are evaluated first. case ir.OADD, ir.OSUB, ir.ONEG, ir.OMUL: - if thearch.SoftFloat && (isFloat[n.Type.Etype] || isComplex[n.Type.Etype]) { + if thearch.SoftFloat && (isFloat[n.Type().Etype] || isComplex[n.Type().Etype]) { return true } case ir.OLT, ir.OEQ, ir.ONE, ir.OLE, ir.OGE, ir.OGT: - if thearch.SoftFloat && (isFloat[n.Left.Type.Etype] || isComplex[n.Left.Type.Etype]) { + if thearch.SoftFloat && (isFloat[n.Left().Type().Etype] || isComplex[n.Left().Type().Etype]) { return true } case ir.OCONV: - if thearch.SoftFloat && ((isFloat[n.Type.Etype] || isComplex[n.Type.Etype]) || (isFloat[n.Left.Type.Etype] || isComplex[n.Left.Type.Etype])) { + if thearch.SoftFloat && ((isFloat[n.Type().Etype] || isComplex[n.Type().Etype]) || (isFloat[n.Left().Type().Etype] || isComplex[n.Left().Type().Etype])) { return true } } - if n.Left != nil && n.Left.HasCall() { + if n.Left() != nil && n.Left().HasCall() { return true } - if n.Right != nil && n.Right.HasCall() { + if n.Right() != nil && n.Right().HasCall() { return true } return false @@ -745,45 +745,45 @@ func safeexpr(n *ir.Node, init *ir.Nodes) *ir.Node { return nil } - if n.Ninit.Len() != 0 { - walkstmtlist(n.Ninit.Slice()) - init.AppendNodes(&n.Ninit) + if n.Init().Len() != 0 { + walkstmtlist(n.Init().Slice()) + init.AppendNodes(n.PtrInit()) } - switch n.Op { + switch n.Op() { case ir.ONAME, ir.OLITERAL, ir.ONIL: return n case ir.ODOT, ir.OLEN, ir.OCAP: - l := safeexpr(n.Left, init) - if l == n.Left { + l := safeexpr(n.Left(), init) + if l == n.Left() { return n } r := ir.Copy(n) - r.Left = l + r.SetLeft(l) r = typecheck(r, ctxExpr) r = walkexpr(r, init) return r case ir.ODOTPTR, ir.ODEREF: - l := safeexpr(n.Left, init) - if l == n.Left { + l := safeexpr(n.Left(), init) + if l == n.Left() { return n } a := ir.Copy(n) - a.Left = l + a.SetLeft(l) a = walkexpr(a, init) return a case ir.OINDEX, ir.OINDEXMAP: - l := safeexpr(n.Left, init) - r := safeexpr(n.Right, init) - if l == n.Left && r == n.Right { + l := safeexpr(n.Left(), init) + r := safeexpr(n.Right(), init) + if l == n.Left() && r == n.Right() { return n } a := ir.Copy(n) - a.Left = l - a.Right = r + a.SetLeft(l) + a.SetRight(r) a = walkexpr(a, init) return a @@ -812,12 +812,12 @@ func copyexpr(n *ir.Node, t *types.Type, init *ir.Nodes) *ir.Node { // return side-effect free and cheap n, appending side effects to init. // result may not be assignable. func cheapexpr(n *ir.Node, init *ir.Nodes) *ir.Node { - switch n.Op { + switch n.Op() { case ir.ONAME, ir.OLITERAL, ir.ONIL: return n } - return copyexpr(n, n.Type, init) + return copyexpr(n, n.Type(), init) } // Code to resolve elided DOTs in embedded types. @@ -958,20 +958,20 @@ func dotpath(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) ( // will give shortest unique addressing. // modify the tree with missing type names. func adddot(n *ir.Node) *ir.Node { - n.Left = typecheck(n.Left, ctxType|ctxExpr) - if n.Left.Diag() { + n.SetLeft(typecheck(n.Left(), ctxType|ctxExpr)) + if n.Left().Diag() { n.SetDiag(true) } - t := n.Left.Type + t := n.Left().Type() if t == nil { return n } - if n.Left.Op == ir.OTYPE { + if n.Left().Op() == ir.OTYPE { return n } - s := n.Sym + s := n.Sym() if s == nil { return n } @@ -980,12 +980,12 @@ func adddot(n *ir.Node) *ir.Node { case path != nil: // rebuild elided dots for c := len(path) - 1; c >= 0; c-- { - n.Left = nodSym(ir.ODOT, n.Left, path[c].field.Sym) - n.Left.SetImplicit(true) + n.SetLeft(nodSym(ir.ODOT, n.Left(), path[c].field.Sym)) + n.Left().SetImplicit(true) } case ambig: base.Errorf("ambiguous selector %v", n) - n.Left = nil + n.SetLeft(nil) } return n @@ -1127,7 +1127,7 @@ func structargs(tl *types.Type, mustname bool) []*ir.Node { gen++ } a := symfield(s, t.Type) - a.Pos = t.Pos + a.SetPos(t.Pos) a.SetIsDDD(t.IsDDD()) args = append(args, a) } @@ -1177,14 +1177,14 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { dclcontext = ir.PEXTERN tfn := ir.Nod(ir.OTFUNC, nil, nil) - tfn.Left = namedfield(".this", rcvr) - tfn.List.Set(structargs(method.Type.Params(), true)) - tfn.Rlist.Set(structargs(method.Type.Results(), false)) + tfn.SetLeft(namedfield(".this", rcvr)) + tfn.PtrList().Set(structargs(method.Type.Params(), true)) + tfn.PtrRlist().Set(structargs(method.Type.Results(), false)) fn := dclfunc(newnam, tfn) - fn.Func.SetDupok(true) + fn.Func().SetDupok(true) - nthis := ir.AsNode(tfn.Type.Recv().Nname) + nthis := ir.AsNode(tfn.Type().Recv().Nname) methodrcvr := method.Type.Recv().Type @@ -1192,10 +1192,10 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { if rcvr.IsPtr() && rcvr.Elem() == methodrcvr { // generating wrapper from *T to T. n := ir.Nod(ir.OIF, nil, nil) - n.Left = ir.Nod(ir.OEQ, nthis, nodnil()) + n.SetLeft(ir.Nod(ir.OEQ, nthis, nodnil())) call := ir.Nod(ir.OCALL, syslook("panicwrap"), nil) - n.Nbody.Set1(call) - fn.Nbody.Append(n) + n.PtrBody().Set1(call) + fn.PtrBody().Append(n) } dot := adddot(nodSym(ir.OXDOT, nthis, method.Sym)) @@ -1209,29 +1209,29 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { // value for that function. if !instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !isifacemethod(method.Type) && !(thearch.LinkArch.Name == "ppc64le" && base.Ctxt.Flag_dynlink) { // generate tail call: adjust pointer receiver and jump to embedded method. - dot = dot.Left // skip final .M + dot = dot.Left() // skip final .M // TODO(mdempsky): Remove dependency on dotlist. if !dotlist[0].field.Type.IsPtr() { dot = ir.Nod(ir.OADDR, dot, nil) } as := ir.Nod(ir.OAS, nthis, convnop(dot, rcvr)) - fn.Nbody.Append(as) - fn.Nbody.Append(nodSym(ir.ORETJMP, nil, methodSym(methodrcvr, method.Sym))) + fn.PtrBody().Append(as) + fn.PtrBody().Append(nodSym(ir.ORETJMP, nil, methodSym(methodrcvr, method.Sym))) } else { - fn.Func.SetWrapper(true) // ignore frame for panic+recover matching + fn.Func().SetWrapper(true) // ignore frame for panic+recover matching call := ir.Nod(ir.OCALL, dot, nil) - call.List.Set(paramNnames(tfn.Type)) - call.SetIsDDD(tfn.Type.IsVariadic()) + call.PtrList().Set(paramNnames(tfn.Type())) + call.SetIsDDD(tfn.Type().IsVariadic()) if method.Type.NumResults() > 0 { n := ir.Nod(ir.ORETURN, nil, nil) - n.List.Set1(call) + n.PtrList().Set1(call) call = n } - fn.Nbody.Append(call) + fn.PtrBody().Append(call) } if false && base.Flag.LowerR != 0 { - ir.DumpList("genwrapper body", fn.Nbody) + ir.DumpList("genwrapper body", fn.Body()) } funcbody() @@ -1242,7 +1242,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { fn = typecheck(fn, ctxStmt) Curfn = fn - typecheckslice(fn.Nbody.Slice(), ctxStmt) + typecheckslice(fn.Body().Slice(), ctxStmt) // Inline calls within (*T).M wrappers. This is safe because we only // generate those wrappers within the same compilation unit as (T).M. @@ -1269,13 +1269,13 @@ func hashmem(t *types.Type) *ir.Node { n := NewName(sym) setNodeNameFunc(n) - n.Type = functype(nil, []*ir.Node{ + n.SetType(functype(nil, []*ir.Node{ anonfield(types.NewPtr(t)), anonfield(types.Types[types.TUINTPTR]), anonfield(types.Types[types.TUINTPTR]), }, []*ir.Node{ anonfield(types.Types[types.TUINTPTR]), - }) + })) return n } @@ -1403,16 +1403,16 @@ func listtreecopy(l []*ir.Node, pos src.XPos) []*ir.Node { func liststmt(l []*ir.Node) *ir.Node { n := ir.Nod(ir.OBLOCK, nil, nil) - n.List.Set(l) + n.PtrList().Set(l) if len(l) != 0 { - n.Pos = l[0].Pos + n.SetPos(l[0].Pos()) } return n } func ngotype(n *ir.Node) *types.Sym { - if n.Type != nil { - return typenamesym(n.Type) + if n.Type() != nil { + return typenamesym(n.Type()) } return nil } @@ -1426,11 +1426,11 @@ func addinit(n *ir.Node, init []*ir.Node) *ir.Node { if ir.MayBeShared(n) { // Introduce OCONVNOP to hold init list. n = ir.Nod(ir.OCONVNOP, n, nil) - n.Type = n.Left.Type + n.SetType(n.Left().Type()) n.SetTypecheck(1) } - n.Ninit.Prepend(init...) + n.PtrInit().Prepend(init...) n.SetHasCall(true) return n } @@ -1520,10 +1520,10 @@ func isdirectiface(t *types.Type) bool { // itabType loads the _type field from a runtime.itab struct. func itabType(itab *ir.Node) *ir.Node { typ := nodSym(ir.ODOTPTR, itab, nil) - typ.Type = types.NewPtr(types.Types[types.TUINT8]) + typ.SetType(types.NewPtr(types.Types[types.TUINT8])) typ.SetTypecheck(1) - typ.Xoffset = int64(Widthptr) // offset of _type in runtime.itab - typ.SetBounded(true) // guaranteed not to fault + typ.SetOffset(int64(Widthptr)) // offset of _type in runtime.itab + typ.SetBounded(true) // guaranteed not to fault return typ } @@ -1536,14 +1536,14 @@ func ifaceData(pos src.XPos, n *ir.Node, t *types.Type) *ir.Node { } ptr := nodlSym(pos, ir.OIDATA, n, nil) if isdirectiface(t) { - ptr.Type = t + ptr.SetType(t) ptr.SetTypecheck(1) return ptr } - ptr.Type = types.NewPtr(t) + ptr.SetType(types.NewPtr(t)) ptr.SetTypecheck(1) ind := ir.NodAt(pos, ir.ODEREF, ptr, nil) - ind.Type = t + ind.SetType(t) ind.SetTypecheck(1) ind.SetBounded(true) return ind @@ -1553,8 +1553,8 @@ func ifaceData(pos src.XPos, n *ir.Node, t *types.Type) *ir.Node { // This is where t was declared or where it appeared as a type expression. func typePos(t *types.Type) src.XPos { n := ir.AsNode(t.Nod) - if n == nil || !n.Pos.IsKnown() { + if n == nil || !n.Pos().IsKnown() { base.Fatalf("bad type: %v", t) } - return n.Pos + return n.Pos() } diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go index f3195df79a..c85483fafa 100644 --- a/src/cmd/compile/internal/gc/swt.go +++ b/src/cmd/compile/internal/gc/swt.go @@ -16,8 +16,8 @@ import ( // typecheckswitch typechecks a switch statement. func typecheckswitch(n *ir.Node) { - typecheckslice(n.Ninit.Slice(), ctxStmt) - if n.Left != nil && n.Left.Op == ir.OTYPESW { + typecheckslice(n.Init().Slice(), ctxStmt) + if n.Left() != nil && n.Left().Op() == ir.OTYPESW { typecheckTypeSwitch(n) } else { typecheckExprSwitch(n) @@ -25,27 +25,27 @@ func typecheckswitch(n *ir.Node) { } func typecheckTypeSwitch(n *ir.Node) { - n.Left.Right = typecheck(n.Left.Right, ctxExpr) - t := n.Left.Right.Type + n.Left().SetRight(typecheck(n.Left().Right(), ctxExpr)) + t := n.Left().Right().Type() if t != nil && !t.IsInterface() { - base.ErrorfAt(n.Pos, "cannot type switch on non-interface value %L", n.Left.Right) + base.ErrorfAt(n.Pos(), "cannot type switch on non-interface value %L", n.Left().Right()) t = nil } // We don't actually declare the type switch's guarded // declaration itself. So if there are no cases, we won't // notice that it went unused. - if v := n.Left.Left; v != nil && !ir.IsBlank(v) && n.List.Len() == 0 { - base.ErrorfAt(v.Pos, "%v declared but not used", v.Sym) + if v := n.Left().Left(); v != nil && !ir.IsBlank(v) && n.List().Len() == 0 { + base.ErrorfAt(v.Pos(), "%v declared but not used", v.Sym()) } var defCase, nilCase *ir.Node var ts typeSet - for _, ncase := range n.List.Slice() { - ls := ncase.List.Slice() + for _, ncase := range n.List().Slice() { + ls := ncase.List().Slice() if len(ls) == 0 { // default: if defCase != nil { - base.ErrorfAt(ncase.Pos, "multiple defaults in switch (first at %v)", ir.Line(defCase)) + base.ErrorfAt(ncase.Pos(), "multiple defaults in switch (first at %v)", ir.Line(defCase)) } else { defCase = ncase } @@ -54,7 +54,7 @@ func typecheckTypeSwitch(n *ir.Node) { for i := range ls { ls[i] = typecheck(ls[i], ctxExpr|ctxType) n1 := ls[i] - if t == nil || n1.Type == nil { + if t == nil || n1.Type() == nil { continue } @@ -63,36 +63,36 @@ func typecheckTypeSwitch(n *ir.Node) { switch { case ir.IsNil(n1): // case nil: if nilCase != nil { - base.ErrorfAt(ncase.Pos, "multiple nil cases in type switch (first at %v)", ir.Line(nilCase)) + base.ErrorfAt(ncase.Pos(), "multiple nil cases in type switch (first at %v)", ir.Line(nilCase)) } else { nilCase = ncase } - case n1.Op != ir.OTYPE: - base.ErrorfAt(ncase.Pos, "%L is not a type", n1) - case !n1.Type.IsInterface() && !implements(n1.Type, t, &missing, &have, &ptr) && !missing.Broke(): + case n1.Op() != ir.OTYPE: + base.ErrorfAt(ncase.Pos(), "%L is not a type", n1) + case !n1.Type().IsInterface() && !implements(n1.Type(), t, &missing, &have, &ptr) && !missing.Broke(): if have != nil && !have.Broke() { - base.ErrorfAt(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+ - " (wrong type for %v method)\n\thave %v%S\n\twant %v%S", n.Left.Right, n1.Type, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) + base.ErrorfAt(ncase.Pos(), "impossible type switch case: %L cannot have dynamic type %v"+ + " (wrong type for %v method)\n\thave %v%S\n\twant %v%S", n.Left().Right(), n1.Type(), missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) } else if ptr != 0 { - base.ErrorfAt(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+ - " (%v method has pointer receiver)", n.Left.Right, n1.Type, missing.Sym) + base.ErrorfAt(ncase.Pos(), "impossible type switch case: %L cannot have dynamic type %v"+ + " (%v method has pointer receiver)", n.Left().Right(), n1.Type(), missing.Sym) } else { - base.ErrorfAt(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+ - " (missing %v method)", n.Left.Right, n1.Type, missing.Sym) + base.ErrorfAt(ncase.Pos(), "impossible type switch case: %L cannot have dynamic type %v"+ + " (missing %v method)", n.Left().Right(), n1.Type(), missing.Sym) } } - if n1.Op == ir.OTYPE { - ts.add(ncase.Pos, n1.Type) + if n1.Op() == ir.OTYPE { + ts.add(ncase.Pos(), n1.Type()) } } - if ncase.Rlist.Len() != 0 { + if ncase.Rlist().Len() != 0 { // Assign the clause variable's type. vt := t if len(ls) == 1 { - if ls[0].Op == ir.OTYPE { - vt = ls[0].Type + if ls[0].Op() == ir.OTYPE { + vt = ls[0].Type() } else if !ir.IsNil(ls[0]) { // Invalid single-type case; // mark variable as broken. @@ -100,8 +100,8 @@ func typecheckTypeSwitch(n *ir.Node) { } } - nvar := ncase.Rlist.First() - nvar.Type = vt + nvar := ncase.Rlist().First() + nvar.SetType(vt) if vt != nil { nvar = typecheck(nvar, ctxExpr|ctxAssign) } else { @@ -109,10 +109,10 @@ func typecheckTypeSwitch(n *ir.Node) { nvar.SetTypecheck(1) nvar.SetWalkdef(1) } - ncase.Rlist.SetFirst(nvar) + ncase.Rlist().SetFirst(nvar) } - typecheckslice(ncase.Nbody.Slice(), ctxStmt) + typecheckslice(ncase.Body().Slice(), ctxStmt) } } @@ -146,10 +146,10 @@ func (s *typeSet) add(pos src.XPos, typ *types.Type) { func typecheckExprSwitch(n *ir.Node) { t := types.Types[types.TBOOL] - if n.Left != nil { - n.Left = typecheck(n.Left, ctxExpr) - n.Left = defaultlit(n.Left, nil) - t = n.Left.Type + if n.Left() != nil { + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetLeft(defaultlit(n.Left(), nil)) + t = n.Left().Type() } var nilonly string @@ -164,9 +164,9 @@ func typecheckExprSwitch(n *ir.Node) { case !IsComparable(t): if t.IsStruct() { - base.ErrorfAt(n.Pos, "cannot switch on %L (struct containing %v cannot be compared)", n.Left, IncomparableField(t).Type) + base.ErrorfAt(n.Pos(), "cannot switch on %L (struct containing %v cannot be compared)", n.Left(), IncomparableField(t).Type) } else { - base.ErrorfAt(n.Pos, "cannot switch on %L", n.Left) + base.ErrorfAt(n.Pos(), "cannot switch on %L", n.Left()) } t = nil } @@ -174,11 +174,11 @@ func typecheckExprSwitch(n *ir.Node) { var defCase *ir.Node var cs constSet - for _, ncase := range n.List.Slice() { - ls := ncase.List.Slice() + for _, ncase := range n.List().Slice() { + ls := ncase.List().Slice() if len(ls) == 0 { // default: if defCase != nil { - base.ErrorfAt(ncase.Pos, "multiple defaults in switch (first at %v)", ir.Line(defCase)) + base.ErrorfAt(ncase.Pos(), "multiple defaults in switch (first at %v)", ir.Line(defCase)) } else { defCase = ncase } @@ -189,22 +189,22 @@ func typecheckExprSwitch(n *ir.Node) { ls[i] = typecheck(ls[i], ctxExpr) ls[i] = defaultlit(ls[i], t) n1 := ls[i] - if t == nil || n1.Type == nil { + if t == nil || n1.Type() == nil { continue } if nilonly != "" && !ir.IsNil(n1) { - base.ErrorfAt(ncase.Pos, "invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left) - } else if t.IsInterface() && !n1.Type.IsInterface() && !IsComparable(n1.Type) { - base.ErrorfAt(ncase.Pos, "invalid case %L in switch (incomparable type)", n1) + base.ErrorfAt(ncase.Pos(), "invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left()) + } else if t.IsInterface() && !n1.Type().IsInterface() && !IsComparable(n1.Type()) { + base.ErrorfAt(ncase.Pos(), "invalid case %L in switch (incomparable type)", n1) } else { - op1, _ := assignop(n1.Type, t) - op2, _ := assignop(t, n1.Type) + op1, _ := assignop(n1.Type(), t) + op2, _ := assignop(t, n1.Type()) if op1 == ir.OXXX && op2 == ir.OXXX { - if n.Left != nil { - base.ErrorfAt(ncase.Pos, "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left, n1.Type, t) + if n.Left() != nil { + base.ErrorfAt(ncase.Pos(), "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left(), n1.Type(), t) } else { - base.ErrorfAt(ncase.Pos, "invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type) + base.ErrorfAt(ncase.Pos(), "invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type()) } } } @@ -215,23 +215,23 @@ func typecheckExprSwitch(n *ir.Node) { // case GOARCH == "arm" && GOARM == "5": // case GOARCH == "arm": // which would both evaluate to false for non-ARM compiles. - if !n1.Type.IsBoolean() { - cs.add(ncase.Pos, n1, "case", "switch") + if !n1.Type().IsBoolean() { + cs.add(ncase.Pos(), n1, "case", "switch") } } - typecheckslice(ncase.Nbody.Slice(), ctxStmt) + typecheckslice(ncase.Body().Slice(), ctxStmt) } } // walkswitch walks a switch statement. func walkswitch(sw *ir.Node) { // Guard against double walk, see #25776. - if sw.List.Len() == 0 && sw.Nbody.Len() > 0 { + if sw.List().Len() == 0 && sw.Body().Len() > 0 { return // Was fatal, but eliminating every possible source of double-walking is hard } - if sw.Left != nil && sw.Left.Op == ir.OTYPESW { + if sw.Left() != nil && sw.Left().Op() == ir.OTYPESW { walkTypeSwitch(sw) } else { walkExprSwitch(sw) @@ -243,8 +243,8 @@ func walkswitch(sw *ir.Node) { func walkExprSwitch(sw *ir.Node) { lno := setlineno(sw) - cond := sw.Left - sw.Left = nil + cond := sw.Left() + sw.SetLeft(nil) // convert switch {...} to switch true {...} if cond == nil { @@ -260,13 +260,13 @@ func walkExprSwitch(sw *ir.Node) { // because walkexpr will lower the string // conversion into a runtime call. // See issue 24937 for more discussion. - if cond.Op == ir.OBYTES2STR && allCaseExprsAreSideEffectFree(sw) { - cond.Op = ir.OBYTES2STRTMP + if cond.Op() == ir.OBYTES2STR && allCaseExprsAreSideEffectFree(sw) { + cond.SetOp(ir.OBYTES2STRTMP) } - cond = walkexpr(cond, &sw.Ninit) - if cond.Op != ir.OLITERAL && cond.Op != ir.ONIL { - cond = copyexpr(cond, cond.Type, &sw.Nbody) + cond = walkexpr(cond, sw.PtrInit()) + if cond.Op() != ir.OLITERAL && cond.Op() != ir.ONIL { + cond = copyexpr(cond, cond.Type(), sw.PtrBody()) } base.Pos = lno @@ -277,43 +277,43 @@ func walkExprSwitch(sw *ir.Node) { var defaultGoto *ir.Node var body ir.Nodes - for _, ncase := range sw.List.Slice() { + for _, ncase := range sw.List().Slice() { label := autolabel(".s") - jmp := npos(ncase.Pos, nodSym(ir.OGOTO, nil, label)) + jmp := npos(ncase.Pos(), nodSym(ir.OGOTO, nil, label)) // Process case dispatch. - if ncase.List.Len() == 0 { + if ncase.List().Len() == 0 { if defaultGoto != nil { base.Fatalf("duplicate default case not detected during typechecking") } defaultGoto = jmp } - for _, n1 := range ncase.List.Slice() { - s.Add(ncase.Pos, n1, jmp) + for _, n1 := range ncase.List().Slice() { + s.Add(ncase.Pos(), n1, jmp) } // Process body. - body.Append(npos(ncase.Pos, nodSym(ir.OLABEL, nil, label))) - body.Append(ncase.Nbody.Slice()...) - if fall, pos := hasFall(ncase.Nbody.Slice()); !fall { + body.Append(npos(ncase.Pos(), nodSym(ir.OLABEL, nil, label))) + body.Append(ncase.Body().Slice()...) + if fall, pos := hasFall(ncase.Body().Slice()); !fall { br := ir.Nod(ir.OBREAK, nil, nil) - br.Pos = pos + br.SetPos(pos) body.Append(br) } } - sw.List.Set(nil) + sw.PtrList().Set(nil) if defaultGoto == nil { br := ir.Nod(ir.OBREAK, nil, nil) - br.Pos = br.Pos.WithNotStmt() + br.SetPos(br.Pos().WithNotStmt()) defaultGoto = br } - s.Emit(&sw.Nbody) - sw.Nbody.Append(defaultGoto) - sw.Nbody.AppendNodes(&body) - walkstmtlist(sw.Nbody.Slice()) + s.Emit(sw.PtrBody()) + sw.PtrBody().Append(defaultGoto) + sw.PtrBody().AppendNodes(&body) + walkstmtlist(sw.Body().Slice()) } // An exprSwitch walks an expression switch. @@ -332,7 +332,7 @@ type exprClause struct { func (s *exprSwitch) Add(pos src.XPos, expr, jmp *ir.Node) { c := exprClause{pos: pos, lo: expr, hi: expr, jmp: jmp} - if okforcmp[s.exprname.Type.Etype] && expr.Op == ir.OLITERAL { + if okforcmp[s.exprname.Type().Etype] && expr.Op() == ir.OLITERAL { s.clauses = append(s.clauses, c) return } @@ -359,7 +359,7 @@ func (s *exprSwitch) flush() { // (e.g., sort.Slice doesn't need to invoke the less function // when there's only a single slice element). - if s.exprname.Type.IsString() && len(cc) >= 2 { + if s.exprname.Type().IsString() && len(cc) >= 2 { // Sort strings by length and then by value. It is // much cheaper to compare lengths than values, and // all we need here is consistency. We respect this @@ -395,8 +395,8 @@ func (s *exprSwitch) flush() { }, func(i int, nif *ir.Node) { run := runs[i] - nif.Left = ir.Nod(ir.OEQ, ir.Nod(ir.OLEN, s.exprname, nil), nodintconst(runLen(run))) - s.search(run, &nif.Nbody) + nif.SetLeft(ir.Nod(ir.OEQ, ir.Nod(ir.OLEN, s.exprname, nil), nodintconst(runLen(run)))) + s.search(run, nif.PtrBody()) }, ) return @@ -407,7 +407,7 @@ func (s *exprSwitch) flush() { }) // Merge consecutive integer cases. - if s.exprname.Type.IsInteger() { + if s.exprname.Type().IsInteger() { merged := cc[:1] for _, c := range cc[1:] { last := &merged[len(merged)-1] @@ -430,8 +430,8 @@ func (s *exprSwitch) search(cc []exprClause, out *ir.Nodes) { }, func(i int, nif *ir.Node) { c := &cc[i] - nif.Left = c.test(s.exprname) - nif.Nbody.Set1(c.jmp) + nif.SetLeft(c.test(s.exprname)) + nif.PtrBody().Set1(c.jmp) }, ) } @@ -445,7 +445,7 @@ func (c *exprClause) test(exprname *ir.Node) *ir.Node { } // Optimize "switch true { ...}" and "switch false { ... }". - if ir.IsConst(exprname, constant.Bool) && !c.lo.Type.IsInterface() { + if ir.IsConst(exprname, constant.Bool) && !c.lo.Type().IsInterface() { if exprname.BoolVal() { return c.lo } else { @@ -464,12 +464,12 @@ func allCaseExprsAreSideEffectFree(sw *ir.Node) bool { // Restricting to constants is simple and probably powerful // enough. - for _, ncase := range sw.List.Slice() { - if ncase.Op != ir.OCASE { - base.Fatalf("switch string(byteslice) bad op: %v", ncase.Op) + for _, ncase := range sw.List().Slice() { + if ncase.Op() != ir.OCASE { + base.Fatalf("switch string(byteslice) bad op: %v", ncase.Op()) } - for _, v := range ncase.List.Slice() { - if v.Op != ir.OLITERAL { + for _, v := range ncase.List().Slice() { + if v.Op() != ir.OLITERAL { return false } } @@ -486,24 +486,24 @@ func hasFall(stmts []*ir.Node) (bool, src.XPos) { // nodes will be at the end of the list. i := len(stmts) - 1 - for i >= 0 && stmts[i].Op == ir.OVARKILL { + for i >= 0 && stmts[i].Op() == ir.OVARKILL { i-- } if i < 0 { return false, src.NoXPos } - return stmts[i].Op == ir.OFALL, stmts[i].Pos + return stmts[i].Op() == ir.OFALL, stmts[i].Pos() } // walkTypeSwitch generates an AST that implements sw, where sw is a // type switch. func walkTypeSwitch(sw *ir.Node) { var s typeSwitch - s.facename = sw.Left.Right - sw.Left = nil + s.facename = sw.Left().Right() + sw.SetLeft(nil) - s.facename = walkexpr(s.facename, &sw.Ninit) - s.facename = copyexpr(s.facename, s.facename.Type, &sw.Nbody) + s.facename = walkexpr(s.facename, sw.PtrInit()) + s.facename = copyexpr(s.facename, s.facename.Type(), sw.PtrBody()) s.okname = temp(types.Types[types.TBOOL]) // Get interface descriptor word. @@ -518,54 +518,54 @@ func walkTypeSwitch(sw *ir.Node) { // h := e._type.hash // Use a similar strategy for non-empty interfaces. ifNil := ir.Nod(ir.OIF, nil, nil) - ifNil.Left = ir.Nod(ir.OEQ, itab, nodnil()) + ifNil.SetLeft(ir.Nod(ir.OEQ, itab, nodnil())) base.Pos = base.Pos.WithNotStmt() // disable statement marks after the first check. - ifNil.Left = typecheck(ifNil.Left, ctxExpr) - ifNil.Left = defaultlit(ifNil.Left, nil) + ifNil.SetLeft(typecheck(ifNil.Left(), ctxExpr)) + ifNil.SetLeft(defaultlit(ifNil.Left(), nil)) // ifNil.Nbody assigned at end. - sw.Nbody.Append(ifNil) + sw.PtrBody().Append(ifNil) // Load hash from type or itab. dotHash := nodSym(ir.ODOTPTR, itab, nil) - dotHash.Type = types.Types[types.TUINT32] + dotHash.SetType(types.Types[types.TUINT32]) dotHash.SetTypecheck(1) - if s.facename.Type.IsEmptyInterface() { - dotHash.Xoffset = int64(2 * Widthptr) // offset of hash in runtime._type + if s.facename.Type().IsEmptyInterface() { + dotHash.SetOffset(int64(2 * Widthptr)) // offset of hash in runtime._type } else { - dotHash.Xoffset = int64(2 * Widthptr) // offset of hash in runtime.itab + dotHash.SetOffset(int64(2 * Widthptr)) // offset of hash in runtime.itab } dotHash.SetBounded(true) // guaranteed not to fault - s.hashname = copyexpr(dotHash, dotHash.Type, &sw.Nbody) + s.hashname = copyexpr(dotHash, dotHash.Type(), sw.PtrBody()) br := ir.Nod(ir.OBREAK, nil, nil) var defaultGoto, nilGoto *ir.Node var body ir.Nodes - for _, ncase := range sw.List.Slice() { + for _, ncase := range sw.List().Slice() { var caseVar *ir.Node - if ncase.Rlist.Len() != 0 { - caseVar = ncase.Rlist.First() + if ncase.Rlist().Len() != 0 { + caseVar = ncase.Rlist().First() } // For single-type cases with an interface type, // we initialize the case variable as part of the type assertion. // In other cases, we initialize it in the body. var singleType *types.Type - if ncase.List.Len() == 1 && ncase.List.First().Op == ir.OTYPE { - singleType = ncase.List.First().Type + if ncase.List().Len() == 1 && ncase.List().First().Op() == ir.OTYPE { + singleType = ncase.List().First().Type() } caseVarInitialized := false label := autolabel(".s") - jmp := npos(ncase.Pos, nodSym(ir.OGOTO, nil, label)) + jmp := npos(ncase.Pos(), nodSym(ir.OGOTO, nil, label)) - if ncase.List.Len() == 0 { // default: + if ncase.List().Len() == 0 { // default: if defaultGoto != nil { base.Fatalf("duplicate default case not detected during typechecking") } defaultGoto = jmp } - for _, n1 := range ncase.List.Slice() { + for _, n1 := range ncase.List().Slice() { if ir.IsNil(n1) { // case nil: if nilGoto != nil { base.Fatalf("duplicate nil case not detected during typechecking") @@ -575,14 +575,14 @@ func walkTypeSwitch(sw *ir.Node) { } if singleType != nil && singleType.IsInterface() { - s.Add(ncase.Pos, n1.Type, caseVar, jmp) + s.Add(ncase.Pos(), n1.Type(), caseVar, jmp) caseVarInitialized = true } else { - s.Add(ncase.Pos, n1.Type, nil, jmp) + s.Add(ncase.Pos(), n1.Type(), nil, jmp) } } - body.Append(npos(ncase.Pos, nodSym(ir.OLABEL, nil, label))) + body.Append(npos(ncase.Pos(), nodSym(ir.OLABEL, nil, label))) if caseVar != nil && !caseVarInitialized { val := s.facename if singleType != nil { @@ -590,19 +590,19 @@ func walkTypeSwitch(sw *ir.Node) { if singleType.IsInterface() { base.Fatalf("singleType interface should have been handled in Add") } - val = ifaceData(ncase.Pos, s.facename, singleType) + val = ifaceData(ncase.Pos(), s.facename, singleType) } l := []*ir.Node{ - ir.NodAt(ncase.Pos, ir.ODCL, caseVar, nil), - ir.NodAt(ncase.Pos, ir.OAS, caseVar, val), + ir.NodAt(ncase.Pos(), ir.ODCL, caseVar, nil), + ir.NodAt(ncase.Pos(), ir.OAS, caseVar, val), } typecheckslice(l, ctxStmt) body.Append(l...) } - body.Append(ncase.Nbody.Slice()...) + body.Append(ncase.Body().Slice()...) body.Append(br) } - sw.List.Set(nil) + sw.PtrList().Set(nil) if defaultGoto == nil { defaultGoto = br @@ -610,13 +610,13 @@ func walkTypeSwitch(sw *ir.Node) { if nilGoto == nil { nilGoto = defaultGoto } - ifNil.Nbody.Set1(nilGoto) + ifNil.PtrBody().Set1(nilGoto) - s.Emit(&sw.Nbody) - sw.Nbody.Append(defaultGoto) - sw.Nbody.AppendNodes(&body) + s.Emit(sw.PtrBody()) + sw.PtrBody().Append(defaultGoto) + sw.PtrBody().AppendNodes(&body) - walkstmtlist(sw.Nbody.Slice()) + walkstmtlist(sw.Body().Slice()) } // A typeSwitch walks a type switch. @@ -650,18 +650,18 @@ func (s *typeSwitch) Add(pos src.XPos, typ *types.Type, caseVar, jmp *ir.Node) { // cv, ok = iface.(type) as := ir.NodAt(pos, ir.OAS2, nil, nil) - as.List.Set2(caseVar, s.okname) // cv, ok = + as.PtrList().Set2(caseVar, s.okname) // cv, ok = dot := ir.NodAt(pos, ir.ODOTTYPE, s.facename, nil) - dot.Type = typ // iface.(type) - as.Rlist.Set1(dot) + dot.SetType(typ) // iface.(type) + as.PtrRlist().Set1(dot) as = typecheck(as, ctxStmt) as = walkexpr(as, &body) body.Append(as) // if ok { goto label } nif := ir.NodAt(pos, ir.OIF, nil, nil) - nif.Left = s.okname - nif.Nbody.Set1(jmp) + nif.SetLeft(s.okname) + nif.PtrBody().Set1(jmp) body.Append(nif) if !typ.IsInterface() { @@ -710,8 +710,8 @@ func (s *typeSwitch) flush() { // TODO(mdempsky): Omit hash equality check if // there's only one type. c := cc[i] - nif.Left = ir.Nod(ir.OEQ, s.hashname, nodintconst(int64(c.hash))) - nif.Nbody.AppendNodes(&c.body) + nif.SetLeft(ir.Nod(ir.OEQ, s.hashname, nodintconst(int64(c.hash)))) + nif.PtrBody().AppendNodes(&c.body) }, ) } @@ -736,22 +736,22 @@ func binarySearch(n int, out *ir.Nodes, less func(i int) *ir.Node, leaf func(i i nif := ir.Nod(ir.OIF, nil, nil) leaf(i, nif) base.Pos = base.Pos.WithNotStmt() - nif.Left = typecheck(nif.Left, ctxExpr) - nif.Left = defaultlit(nif.Left, nil) + nif.SetLeft(typecheck(nif.Left(), ctxExpr)) + nif.SetLeft(defaultlit(nif.Left(), nil)) out.Append(nif) - out = &nif.Rlist + out = nif.PtrRlist() } return } half := lo + n/2 nif := ir.Nod(ir.OIF, nil, nil) - nif.Left = less(half) + nif.SetLeft(less(half)) base.Pos = base.Pos.WithNotStmt() - nif.Left = typecheck(nif.Left, ctxExpr) - nif.Left = defaultlit(nif.Left, nil) - do(lo, half, &nif.Nbody) - do(half, hi, &nif.Rlist) + nif.SetLeft(typecheck(nif.Left(), ctxExpr)) + nif.SetLeft(defaultlit(nif.Left(), nil)) + do(lo, half, nif.PtrBody()) + do(half, hi, nif.PtrRlist()) out.Append(nif) } diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index 318f315f16..4bc7f035f5 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -27,8 +27,8 @@ func tracePrint(title string, n *ir.Node) func(np **ir.Node) { var pos, op string var tc uint8 if n != nil { - pos = base.FmtPos(n.Pos) - op = n.Op.String() + pos = base.FmtPos(n.Pos()) + op = n.Op().String() tc = n.Typecheck() } @@ -50,10 +50,10 @@ func tracePrint(title string, n *ir.Node) func(np **ir.Node) { var tc uint8 var typ *types.Type if n != nil { - pos = base.FmtPos(n.Pos) - op = n.Op.String() + pos = base.FmtPos(n.Pos()) + op = n.Op().String() tc = n.Typecheck() - typ = n.Type + typ = n.Type() } skipDowidthForTracing = true @@ -81,7 +81,7 @@ var typecheckdefstack []*ir.Node // resolve ONONAME to definition, if any. func resolve(n *ir.Node) (res *ir.Node) { - if n == nil || n.Op != ir.ONONAME { + if n == nil || n.Op() != ir.ONONAME { return n } @@ -90,7 +90,7 @@ func resolve(n *ir.Node) (res *ir.Node) { defer tracePrint("resolve", n)(&res) } - if n.Sym.Pkg != ir.LocalPkg { + if n.Sym().Pkg != ir.LocalPkg { if inimport { base.Fatalf("recursive inimport") } @@ -100,12 +100,12 @@ func resolve(n *ir.Node) (res *ir.Node) { return n } - r := ir.AsNode(n.Sym.Def) + r := ir.AsNode(n.Sym().Def) if r == nil { return n } - if r.Op == ir.OIOTA { + if r.Op() == ir.OIOTA { if x := getIotaValue(); x >= 0 { return nodintconst(x) } @@ -181,7 +181,7 @@ func cycleFor(start *ir.Node) []*ir.Node { // collect all nodes with same Op var cycle []*ir.Node for _, n := range typecheck_tcstack[i:] { - if n.Op == start.Op { + if n.Op() == start.Op() { cycle = append(cycle, n) } } @@ -220,8 +220,8 @@ func typecheck(n *ir.Node, top int) (res *ir.Node) { lno := setlineno(n) // Skip over parens. - for n.Op == ir.OPAREN { - n = n.Left + for n.Op() == ir.OPAREN { + n = n.Left() } // Resolve definition of name and value of iota lazily. @@ -230,7 +230,7 @@ func typecheck(n *ir.Node, top int) (res *ir.Node) { // Skip typecheck if already done. // But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed. if n.Typecheck() == 1 { - switch n.Op { + switch n.Op() { case ir.ONAME, ir.OTYPE, ir.OLITERAL, ir.OPACK: break @@ -243,7 +243,7 @@ func typecheck(n *ir.Node, top int) (res *ir.Node) { if n.Typecheck() == 2 { // Typechecking loop. Trying printing a meaningful message, // otherwise a stack trace of typechecking. - switch n.Op { + switch n.Op() { // We can already diagnose variables used as types. case ir.ONAME: if top&(ctxExpr|ctxType) == ctxType { @@ -259,20 +259,20 @@ func typecheck(n *ir.Node, top int) (res *ir.Node) { // are substituted. cycle := cycleFor(n) for _, n1 := range cycle { - if n1.Name != nil && !n1.Name.Param.Alias() { + if n1.Name() != nil && !n1.Name().Param.Alias() { // Cycle is ok. But if n is an alias type and doesn't // have a type yet, we have a recursive type declaration // with aliases that we can't handle properly yet. // Report an error rather than crashing later. - if n.Name != nil && n.Name.Param.Alias() && n.Type == nil { - base.Pos = n.Pos + if n.Name() != nil && n.Name().Param.Alias() && n.Type() == nil { + base.Pos = n.Pos() base.Fatalf("cannot handle alias type declaration (issue #25838): %v", n) } base.Pos = lno return n } } - base.ErrorfAt(n.Pos, "invalid recursive type alias %v%s", n, cycleTrace(cycle)) + base.ErrorfAt(n.Pos(), "invalid recursive type alias %v%s", n, cycleTrace(cycle)) } case ir.OLITERAL: @@ -280,7 +280,7 @@ func typecheck(n *ir.Node, top int) (res *ir.Node) { base.Errorf("%v is not a type", n) break } - base.ErrorfAt(n.Pos, "constant definition loop%s", cycleTrace(cycleFor(n))) + base.ErrorfAt(n.Pos(), "constant definition loop%s", cycleTrace(cycleFor(n))) } if base.Errors() == 0 { @@ -318,7 +318,7 @@ func typecheck(n *ir.Node, top int) (res *ir.Node) { // The result of indexlit MUST be assigned back to n, e.g. // n.Left = indexlit(n.Left) func indexlit(n *ir.Node) *ir.Node { - if n != nil && n.Type != nil && n.Type.Etype == types.TIDEAL { + if n != nil && n.Type() != nil && n.Type().Etype == types.TIDEAL { return defaultlit(n, types.Types[types.TINT]) } return n @@ -331,38 +331,38 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { defer tracePrint("typecheck1", n)(&res) } - switch n.Op { + switch n.Op() { case ir.OLITERAL, ir.ONAME, ir.ONONAME, ir.OTYPE: - if n.Sym == nil { + if n.Sym() == nil { break } - if n.Op == ir.ONAME && n.SubOp() != 0 && top&ctxCallee == 0 { - base.Errorf("use of builtin %v not in function call", n.Sym) - n.Type = nil + if n.Op() == ir.ONAME && n.SubOp() != 0 && top&ctxCallee == 0 { + base.Errorf("use of builtin %v not in function call", n.Sym()) + n.SetType(nil) return n } typecheckdef(n) - if n.Op == ir.ONONAME { - n.Type = nil + if n.Op() == ir.ONONAME { + n.SetType(nil) return n } } ok := 0 - switch n.Op { + switch n.Op() { // until typecheck is complete, do nothing. default: ir.Dump("typecheck", n) - base.Fatalf("typecheck %v", n.Op) + base.Fatalf("typecheck %v", n.Op()) // names case ir.OLITERAL: ok |= ctxExpr - if n.Type == nil && n.Val().Kind() == constant.String { + if n.Type() == nil && n.Val().Kind() == constant.String { base.Fatalf("string literal missing type") } @@ -370,8 +370,8 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { ok |= ctxExpr case ir.ONAME: - if n.Name.Decldepth == 0 { - n.Name.Decldepth = decldepth + if n.Name().Decldepth == 0 { + n.Name().Decldepth = decldepth } if n.SubOp() != 0 { ok |= ctxCallee @@ -382,18 +382,18 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { // not a write to the variable if ir.IsBlank(n) { base.Errorf("cannot use _ as value") - n.Type = nil + n.SetType(nil) return n } - n.Name.SetUsed(true) + n.Name().SetUsed(true) } ok |= ctxExpr case ir.OPACK: - base.Errorf("use of package %v without selector", n.Sym) - n.Type = nil + base.Errorf("use of package %v without selector", n.Sym()) + n.SetType(nil) return n case ir.ODDD: @@ -403,142 +403,142 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { case ir.OTYPE: ok |= ctxType - if n.Type == nil { + if n.Type() == nil { return n } case ir.OTARRAY: ok |= ctxType - r := typecheck(n.Right, ctxType) - if r.Type == nil { - n.Type = nil + r := typecheck(n.Right(), ctxType) + if r.Type() == nil { + n.SetType(nil) return n } var t *types.Type - if n.Left == nil { - t = types.NewSlice(r.Type) - } else if n.Left.Op == ir.ODDD { + if n.Left() == nil { + t = types.NewSlice(r.Type()) + } else if n.Left().Op() == ir.ODDD { if !n.Diag() { n.SetDiag(true) base.Errorf("use of [...] array outside of array literal") } - n.Type = nil + n.SetType(nil) return n } else { - n.Left = indexlit(typecheck(n.Left, ctxExpr)) - l := n.Left + n.SetLeft(indexlit(typecheck(n.Left(), ctxExpr))) + l := n.Left() if ir.ConstType(l) != constant.Int { switch { - case l.Type == nil: + case l.Type() == nil: // Error already reported elsewhere. - case l.Type.IsInteger() && l.Op != ir.OLITERAL: + case l.Type().IsInteger() && l.Op() != ir.OLITERAL: base.Errorf("non-constant array bound %v", l) default: base.Errorf("invalid array bound %v", l) } - n.Type = nil + n.SetType(nil) return n } v := l.Val() if doesoverflow(v, types.Types[types.TINT]) { base.Errorf("array bound is too large") - n.Type = nil + n.SetType(nil) return n } if constant.Sign(v) < 0 { base.Errorf("array bound must be non-negative") - n.Type = nil + n.SetType(nil) return n } bound, _ := constant.Int64Val(v) - t = types.NewArray(r.Type, bound) + t = types.NewArray(r.Type(), bound) } setTypeNode(n, t) - n.Left = nil - n.Right = nil + n.SetLeft(nil) + n.SetRight(nil) checkwidth(t) case ir.OTMAP: ok |= ctxType - n.Left = typecheck(n.Left, ctxType) - n.Right = typecheck(n.Right, ctxType) - l := n.Left - r := n.Right - if l.Type == nil || r.Type == nil { - n.Type = nil + n.SetLeft(typecheck(n.Left(), ctxType)) + n.SetRight(typecheck(n.Right(), ctxType)) + l := n.Left() + r := n.Right() + if l.Type() == nil || r.Type() == nil { + n.SetType(nil) return n } - if l.Type.NotInHeap() { + if l.Type().NotInHeap() { base.Errorf("incomplete (or unallocatable) map key not allowed") } - if r.Type.NotInHeap() { + if r.Type().NotInHeap() { base.Errorf("incomplete (or unallocatable) map value not allowed") } - setTypeNode(n, types.NewMap(l.Type, r.Type)) + setTypeNode(n, types.NewMap(l.Type(), r.Type())) mapqueue = append(mapqueue, n) // check map keys when all types are settled - n.Left = nil - n.Right = nil + n.SetLeft(nil) + n.SetRight(nil) case ir.OTCHAN: ok |= ctxType - n.Left = typecheck(n.Left, ctxType) - l := n.Left - if l.Type == nil { - n.Type = nil + n.SetLeft(typecheck(n.Left(), ctxType)) + l := n.Left() + if l.Type() == nil { + n.SetType(nil) return n } - if l.Type.NotInHeap() { + if l.Type().NotInHeap() { base.Errorf("chan of incomplete (or unallocatable) type not allowed") } - setTypeNode(n, types.NewChan(l.Type, n.TChanDir())) - n.Left = nil + setTypeNode(n, types.NewChan(l.Type(), n.TChanDir())) + n.SetLeft(nil) n.ResetAux() case ir.OTSTRUCT: ok |= ctxType - setTypeNode(n, tostruct(n.List.Slice())) - n.List.Set(nil) + setTypeNode(n, tostruct(n.List().Slice())) + n.PtrList().Set(nil) case ir.OTINTER: ok |= ctxType - setTypeNode(n, tointerface(n.List.Slice())) + setTypeNode(n, tointerface(n.List().Slice())) case ir.OTFUNC: ok |= ctxType - setTypeNode(n, functype(n.Left, n.List.Slice(), n.Rlist.Slice())) - n.Left = nil - n.List.Set(nil) - n.Rlist.Set(nil) + setTypeNode(n, functype(n.Left(), n.List().Slice(), n.Rlist().Slice())) + n.SetLeft(nil) + n.PtrList().Set(nil) + n.PtrRlist().Set(nil) // type or expr case ir.ODEREF: - n.Left = typecheck(n.Left, ctxExpr|ctxType) - l := n.Left - t := l.Type + n.SetLeft(typecheck(n.Left(), ctxExpr|ctxType)) + l := n.Left() + t := l.Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } - if l.Op == ir.OTYPE { + if l.Op() == ir.OTYPE { ok |= ctxType - setTypeNode(n, types.NewPtr(l.Type)) - n.Left = nil + setTypeNode(n, types.NewPtr(l.Type())) + n.SetLeft(nil) // Ensure l.Type gets dowidth'd for the backend. Issue 20174. - checkwidth(l.Type) + checkwidth(l.Type()) break } if !t.IsPtr() { if top&(ctxExpr|ctxStmt) != 0 { - base.Errorf("invalid indirect of %L", n.Left) - n.Type = nil + base.Errorf("invalid indirect of %L", n.Left()) + n.SetType(nil) return n } @@ -546,7 +546,7 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { } ok |= ctxExpr - n.Type = t.Elem() + n.SetType(t.Elem()) // arithmetic exprs case ir.OASOP, @@ -572,62 +572,62 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { var l *ir.Node var op ir.Op var r *ir.Node - if n.Op == ir.OASOP { + if n.Op() == ir.OASOP { ok |= ctxStmt - n.Left = typecheck(n.Left, ctxExpr) - n.Right = typecheck(n.Right, ctxExpr) - l = n.Left - r = n.Right - checkassign(n, n.Left) - if l.Type == nil || r.Type == nil { - n.Type = nil + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetRight(typecheck(n.Right(), ctxExpr)) + l = n.Left() + r = n.Right() + checkassign(n, n.Left()) + if l.Type() == nil || r.Type() == nil { + n.SetType(nil) return n } - if n.Implicit() && !okforarith[l.Type.Etype] { - base.Errorf("invalid operation: %v (non-numeric type %v)", n, l.Type) - n.Type = nil + if n.Implicit() && !okforarith[l.Type().Etype] { + base.Errorf("invalid operation: %v (non-numeric type %v)", n, l.Type()) + n.SetType(nil) return n } // TODO(marvin): Fix Node.EType type union. op = n.SubOp() } else { ok |= ctxExpr - n.Left = typecheck(n.Left, ctxExpr) - n.Right = typecheck(n.Right, ctxExpr) - l = n.Left - r = n.Right - if l.Type == nil || r.Type == nil { - n.Type = nil + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetRight(typecheck(n.Right(), ctxExpr)) + l = n.Left() + r = n.Right() + if l.Type() == nil || r.Type() == nil { + n.SetType(nil) return n } - op = n.Op + op = n.Op() } if op == ir.OLSH || op == ir.ORSH { r = defaultlit(r, types.Types[types.TUINT]) - n.Right = r - t := r.Type + n.SetRight(r) + t := r.Type() if !t.IsInteger() { - base.Errorf("invalid operation: %v (shift count type %v, must be integer)", n, r.Type) - n.Type = nil + base.Errorf("invalid operation: %v (shift count type %v, must be integer)", n, r.Type()) + n.SetType(nil) return n } if t.IsSigned() && !langSupported(1, 13, curpkg()) { - base.ErrorfVers("go1.13", "invalid operation: %v (signed shift count type %v)", n, r.Type) - n.Type = nil + base.ErrorfVers("go1.13", "invalid operation: %v (signed shift count type %v)", n, r.Type()) + n.SetType(nil) return n } - t = l.Type + t = l.Type() if t != nil && t.Etype != types.TIDEAL && !t.IsInteger() { base.Errorf("invalid operation: %v (shift of type %v)", n, t) - n.Type = nil + n.SetType(nil) return n } // no defaultlit for left // the outer context gives the type - n.Type = l.Type - if (l.Type == types.UntypedFloat || l.Type == types.UntypedComplex) && r.Op == ir.OLITERAL { - n.Type = types.UntypedInt + n.SetType(l.Type()) + if (l.Type() == types.UntypedFloat || l.Type() == types.UntypedComplex) && r.Op() == ir.OLITERAL { + n.SetType(types.UntypedInt) } break @@ -636,15 +636,15 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { // For "x == x && len(s)", it's better to report that "len(s)" (type int) // can't be used with "&&" than to report that "x == x" (type untyped bool) // can't be converted to int (see issue #41500). - if n.Op == ir.OANDAND || n.Op == ir.OOROR { - if !n.Left.Type.IsBoolean() { - base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op, typekind(n.Left.Type)) - n.Type = nil + if n.Op() == ir.OANDAND || n.Op() == ir.OOROR { + if !n.Left().Type().IsBoolean() { + base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(n.Left().Type())) + n.SetType(nil) return n } - if !n.Right.Type.IsBoolean() { - base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op, typekind(n.Right.Type)) - n.Type = nil + if !n.Right().Type().IsBoolean() { + base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(n.Right().Type())) + n.SetType(nil) return n } } @@ -652,22 +652,22 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { // ideal mixed with non-ideal l, r = defaultlit2(l, r, false) - n.Left = l - n.Right = r - if l.Type == nil || r.Type == nil { - n.Type = nil + n.SetLeft(l) + n.SetRight(r) + if l.Type() == nil || r.Type() == nil { + n.SetType(nil) return n } - t := l.Type + t := l.Type() if t.Etype == types.TIDEAL { - t = r.Type + t = r.Type() } et := t.Etype if et == types.TIDEAL { et = types.TINT } aop := ir.OXXX - if iscmp[n.Op] && t.Etype != types.TIDEAL && !types.Identical(l.Type, r.Type) { + if iscmp[n.Op()] && t.Etype != types.TIDEAL && !types.Identical(l.Type(), r.Type()) { // comparison is okay as long as one side is // assignable to the other. convert so they have // the same type. @@ -676,235 +676,235 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { // in that case, check comparability of the concrete type. // The conversion allocates, so only do it if the concrete type is huge. converted := false - if r.Type.Etype != types.TBLANK { - aop, _ = assignop(l.Type, r.Type) + if r.Type().Etype != types.TBLANK { + aop, _ = assignop(l.Type(), r.Type()) if aop != ir.OXXX { - if r.Type.IsInterface() && !l.Type.IsInterface() && !IsComparable(l.Type) { - base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type)) - n.Type = nil + if r.Type().IsInterface() && !l.Type().IsInterface() && !IsComparable(l.Type()) { + base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type())) + n.SetType(nil) return n } - dowidth(l.Type) - if r.Type.IsInterface() == l.Type.IsInterface() || l.Type.Width >= 1<<16 { + dowidth(l.Type()) + if r.Type().IsInterface() == l.Type().IsInterface() || l.Type().Width >= 1<<16 { l = ir.Nod(aop, l, nil) - l.Type = r.Type + l.SetType(r.Type()) l.SetTypecheck(1) - n.Left = l + n.SetLeft(l) } - t = r.Type + t = r.Type() converted = true } } - if !converted && l.Type.Etype != types.TBLANK { - aop, _ = assignop(r.Type, l.Type) + if !converted && l.Type().Etype != types.TBLANK { + aop, _ = assignop(r.Type(), l.Type()) if aop != ir.OXXX { - if l.Type.IsInterface() && !r.Type.IsInterface() && !IsComparable(r.Type) { - base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type)) - n.Type = nil + if l.Type().IsInterface() && !r.Type().IsInterface() && !IsComparable(r.Type()) { + base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type())) + n.SetType(nil) return n } - dowidth(r.Type) - if r.Type.IsInterface() == l.Type.IsInterface() || r.Type.Width >= 1<<16 { + dowidth(r.Type()) + if r.Type().IsInterface() == l.Type().IsInterface() || r.Type().Width >= 1<<16 { r = ir.Nod(aop, r, nil) - r.Type = l.Type + r.SetType(l.Type()) r.SetTypecheck(1) - n.Right = r + n.SetRight(r) } - t = l.Type + t = l.Type() } } et = t.Etype } - if t.Etype != types.TIDEAL && !types.Identical(l.Type, r.Type) { + if t.Etype != types.TIDEAL && !types.Identical(l.Type(), r.Type()) { l, r = defaultlit2(l, r, true) - if l.Type == nil || r.Type == nil { - n.Type = nil + if l.Type() == nil || r.Type() == nil { + n.SetType(nil) return n } - if l.Type.IsInterface() == r.Type.IsInterface() || aop == 0 { - base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type) - n.Type = nil + if l.Type().IsInterface() == r.Type().IsInterface() || aop == 0 { + base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type(), r.Type()) + n.SetType(nil) return n } } if t.Etype == types.TIDEAL { - t = mixUntyped(l.Type, r.Type) + t = mixUntyped(l.Type(), r.Type()) } if dt := defaultType(t); !okfor[op][dt.Etype] { base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(t)) - n.Type = nil + n.SetType(nil) return n } // okfor allows any array == array, map == map, func == func. // restrict to slice/map/func == nil and nil == slice/map/func. - if l.Type.IsArray() && !IsComparable(l.Type) { - base.Errorf("invalid operation: %v (%v cannot be compared)", n, l.Type) - n.Type = nil + if l.Type().IsArray() && !IsComparable(l.Type()) { + base.Errorf("invalid operation: %v (%v cannot be compared)", n, l.Type()) + n.SetType(nil) return n } - if l.Type.IsSlice() && !ir.IsNil(l) && !ir.IsNil(r) { + if l.Type().IsSlice() && !ir.IsNil(l) && !ir.IsNil(r) { base.Errorf("invalid operation: %v (slice can only be compared to nil)", n) - n.Type = nil + n.SetType(nil) return n } - if l.Type.IsMap() && !ir.IsNil(l) && !ir.IsNil(r) { + if l.Type().IsMap() && !ir.IsNil(l) && !ir.IsNil(r) { base.Errorf("invalid operation: %v (map can only be compared to nil)", n) - n.Type = nil + n.SetType(nil) return n } - if l.Type.Etype == types.TFUNC && !ir.IsNil(l) && !ir.IsNil(r) { + if l.Type().Etype == types.TFUNC && !ir.IsNil(l) && !ir.IsNil(r) { base.Errorf("invalid operation: %v (func can only be compared to nil)", n) - n.Type = nil + n.SetType(nil) return n } - if l.Type.IsStruct() { - if f := IncomparableField(l.Type); f != nil { + if l.Type().IsStruct() { + if f := IncomparableField(l.Type()); f != nil { base.Errorf("invalid operation: %v (struct containing %v cannot be compared)", n, f.Type) - n.Type = nil + n.SetType(nil) return n } } - if iscmp[n.Op] { + if iscmp[n.Op()] { t = types.UntypedBool - n.Type = t + n.SetType(t) n = evalConst(n) - if n.Op != ir.OLITERAL { + if n.Op() != ir.OLITERAL { l, r = defaultlit2(l, r, true) - n.Left = l - n.Right = r + n.SetLeft(l) + n.SetRight(r) } } - if et == types.TSTRING && n.Op == ir.OADD { + if et == types.TSTRING && n.Op() == ir.OADD { // create or update OADDSTR node with list of strings in x + y + z + (w + v) + ... - if l.Op == ir.OADDSTR { + if l.Op() == ir.OADDSTR { orig := n n = l - n.Pos = orig.Pos + n.SetPos(orig.Pos()) } else { - n = ir.NodAt(n.Pos, ir.OADDSTR, nil, nil) - n.List.Set1(l) + n = ir.NodAt(n.Pos(), ir.OADDSTR, nil, nil) + n.PtrList().Set1(l) } - if r.Op == ir.OADDSTR { - n.List.AppendNodes(&r.List) + if r.Op() == ir.OADDSTR { + n.PtrList().AppendNodes(r.PtrList()) } else { - n.List.Append(r) + n.PtrList().Append(r) } } if (op == ir.ODIV || op == ir.OMOD) && ir.IsConst(r, constant.Int) { if constant.Sign(r.Val()) == 0 { base.Errorf("division by zero") - n.Type = nil + n.SetType(nil) return n } } - n.Type = t + n.SetType(t) case ir.OBITNOT, ir.ONEG, ir.ONOT, ir.OPLUS: ok |= ctxExpr - n.Left = typecheck(n.Left, ctxExpr) - l := n.Left - t := l.Type + n.SetLeft(typecheck(n.Left(), ctxExpr)) + l := n.Left() + t := l.Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } - if !okfor[n.Op][defaultType(t).Etype] { - base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op, typekind(t)) - n.Type = nil + if !okfor[n.Op()][defaultType(t).Etype] { + base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(t)) + n.SetType(nil) return n } - n.Type = t + n.SetType(t) // exprs case ir.OADDR: ok |= ctxExpr - n.Left = typecheck(n.Left, ctxExpr) - if n.Left.Type == nil { - n.Type = nil + n.SetLeft(typecheck(n.Left(), ctxExpr)) + if n.Left().Type() == nil { + n.SetType(nil) return n } - switch n.Left.Op { + switch n.Left().Op() { case ir.OARRAYLIT, ir.OMAPLIT, ir.OSLICELIT, ir.OSTRUCTLIT: - n.Op = ir.OPTRLIT + n.SetOp(ir.OPTRLIT) default: - checklvalue(n.Left, "take the address of") - r := outervalue(n.Left) - if r.Op == ir.ONAME { - if r.Orig != r { + checklvalue(n.Left(), "take the address of") + r := outervalue(n.Left()) + if r.Op() == ir.ONAME { + if r.Orig() != r { base.Fatalf("found non-orig name node %v", r) // TODO(mdempsky): What does this mean? } - r.Name.SetAddrtaken(true) - if r.Name.IsClosureVar() && !capturevarscomplete { + r.Name().SetAddrtaken(true) + if r.Name().IsClosureVar() && !capturevarscomplete { // Mark the original variable as Addrtaken so that capturevars // knows not to pass it by value. // But if the capturevars phase is complete, don't touch it, // in case l.Name's containing function has not yet been compiled. - r.Name.Defn.Name.SetAddrtaken(true) + r.Name().Defn.Name().SetAddrtaken(true) } } - n.Left = defaultlit(n.Left, nil) - if n.Left.Type == nil { - n.Type = nil + n.SetLeft(defaultlit(n.Left(), nil)) + if n.Left().Type() == nil { + n.SetType(nil) return n } } - n.Type = types.NewPtr(n.Left.Type) + n.SetType(types.NewPtr(n.Left().Type())) case ir.OCOMPLIT: ok |= ctxExpr n = typecheckcomplit(n) - if n.Type == nil { + if n.Type() == nil { return n } case ir.OXDOT, ir.ODOT: - if n.Op == ir.OXDOT { + if n.Op() == ir.OXDOT { n = adddot(n) - n.Op = ir.ODOT - if n.Left == nil { - n.Type = nil + n.SetOp(ir.ODOT) + if n.Left() == nil { + n.SetType(nil) return n } } - n.Left = typecheck(n.Left, ctxExpr|ctxType) + n.SetLeft(typecheck(n.Left(), ctxExpr|ctxType)) - n.Left = defaultlit(n.Left, nil) + n.SetLeft(defaultlit(n.Left(), nil)) - t := n.Left.Type + t := n.Left().Type() if t == nil { - base.UpdateErrorDot(ir.Line(n), n.Left.String(), n.String()) - n.Type = nil + base.UpdateErrorDot(ir.Line(n), n.Left().String(), n.String()) + n.SetType(nil) return n } - s := n.Sym + s := n.Sym() - if n.Left.Op == ir.OTYPE { + if n.Left().Op() == ir.OTYPE { n = typecheckMethodExpr(n) - if n.Type == nil { + if n.Type() == nil { return n } ok = ctxExpr @@ -914,16 +914,16 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { if t.IsPtr() && !t.Elem().IsInterface() { t = t.Elem() if t == nil { - n.Type = nil + n.SetType(nil) return n } - n.Op = ir.ODOTPTR + n.SetOp(ir.ODOTPTR) checkwidth(t) } - if n.Sym.IsBlank() { + if n.Sym().IsBlank() { base.Errorf("cannot refer to blank field or method") - n.Type = nil + n.SetType(nil) return n } @@ -931,28 +931,28 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { // Legitimate field or method lookup failed, try to explain the error switch { case t.IsEmptyInterface(): - base.Errorf("%v undefined (type %v is interface with no methods)", n, n.Left.Type) + base.Errorf("%v undefined (type %v is interface with no methods)", n, n.Left().Type()) case t.IsPtr() && t.Elem().IsInterface(): // Pointer to interface is almost always a mistake. - base.Errorf("%v undefined (type %v is pointer to interface, not interface)", n, n.Left.Type) + base.Errorf("%v undefined (type %v is pointer to interface, not interface)", n, n.Left().Type()) case lookdot(n, t, 1) != nil: // Field or method matches by name, but it is not exported. - base.Errorf("%v undefined (cannot refer to unexported field or method %v)", n, n.Sym) + base.Errorf("%v undefined (cannot refer to unexported field or method %v)", n, n.Sym()) default: if mt := lookdot(n, t, 2); mt != nil && visible(mt.Sym) { // Case-insensitive lookup. - base.Errorf("%v undefined (type %v has no field or method %v, but does have %v)", n, n.Left.Type, n.Sym, mt.Sym) + base.Errorf("%v undefined (type %v has no field or method %v, but does have %v)", n, n.Left().Type(), n.Sym(), mt.Sym) } else { - base.Errorf("%v undefined (type %v has no field or method %v)", n, n.Left.Type, n.Sym) + base.Errorf("%v undefined (type %v has no field or method %v)", n, n.Left().Type(), n.Sym()) } } - n.Type = nil + n.SetType(nil) return n } - switch n.Op { + switch n.Op() { case ir.ODOTINTER, ir.ODOTMETH: if top&ctxCallee != 0 { ok |= ctxCallee @@ -967,74 +967,74 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { case ir.ODOTTYPE: ok |= ctxExpr - n.Left = typecheck(n.Left, ctxExpr) - n.Left = defaultlit(n.Left, nil) - l := n.Left - t := l.Type + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetLeft(defaultlit(n.Left(), nil)) + l := n.Left() + t := l.Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } if !t.IsInterface() { base.Errorf("invalid type assertion: %v (non-interface type %v on left)", n, t) - n.Type = nil + n.SetType(nil) return n } - if n.Right != nil { - n.Right = typecheck(n.Right, ctxType) - n.Type = n.Right.Type - n.Right = nil - if n.Type == nil { + if n.Right() != nil { + n.SetRight(typecheck(n.Right(), ctxType)) + n.SetType(n.Right().Type()) + n.SetRight(nil) + if n.Type() == nil { return n } } - if n.Type != nil && !n.Type.IsInterface() { + if n.Type() != nil && !n.Type().IsInterface() { var missing, have *types.Field var ptr int - if !implements(n.Type, t, &missing, &have, &ptr) { + if !implements(n.Type(), t, &missing, &have, &ptr) { if have != nil && have.Sym == missing.Sym { base.Errorf("impossible type assertion:\n\t%v does not implement %v (wrong type for %v method)\n"+ - "\t\thave %v%0S\n\t\twant %v%0S", n.Type, t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) + "\t\thave %v%0S\n\t\twant %v%0S", n.Type(), t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) } else if ptr != 0 { - base.Errorf("impossible type assertion:\n\t%v does not implement %v (%v method has pointer receiver)", n.Type, t, missing.Sym) + base.Errorf("impossible type assertion:\n\t%v does not implement %v (%v method has pointer receiver)", n.Type(), t, missing.Sym) } else if have != nil { base.Errorf("impossible type assertion:\n\t%v does not implement %v (missing %v method)\n"+ - "\t\thave %v%0S\n\t\twant %v%0S", n.Type, t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) + "\t\thave %v%0S\n\t\twant %v%0S", n.Type(), t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) } else { - base.Errorf("impossible type assertion:\n\t%v does not implement %v (missing %v method)", n.Type, t, missing.Sym) + base.Errorf("impossible type assertion:\n\t%v does not implement %v (missing %v method)", n.Type(), t, missing.Sym) } - n.Type = nil + n.SetType(nil) return n } } case ir.OINDEX: ok |= ctxExpr - n.Left = typecheck(n.Left, ctxExpr) - n.Left = defaultlit(n.Left, nil) - n.Left = implicitstar(n.Left) - l := n.Left - n.Right = typecheck(n.Right, ctxExpr) - r := n.Right - t := l.Type - if t == nil || r.Type == nil { - n.Type = nil + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetLeft(defaultlit(n.Left(), nil)) + n.SetLeft(implicitstar(n.Left())) + l := n.Left() + n.SetRight(typecheck(n.Right(), ctxExpr)) + r := n.Right() + t := l.Type() + if t == nil || r.Type() == nil { + n.SetType(nil) return n } switch t.Etype { default: base.Errorf("invalid operation: %v (type %v does not support indexing)", n, t) - n.Type = nil + n.SetType(nil) return n case types.TSTRING, types.TARRAY, types.TSLICE: - n.Right = indexlit(n.Right) + n.SetRight(indexlit(n.Right())) if t.IsString() { - n.Type = types.Bytetype + n.SetType(types.Bytetype) } else { - n.Type = t.Elem() + n.SetType(t.Elem()) } why := "string" if t.IsArray() { @@ -1043,83 +1043,83 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { why = "slice" } - if n.Right.Type != nil && !n.Right.Type.IsInteger() { - base.Errorf("non-integer %s index %v", why, n.Right) + if n.Right().Type() != nil && !n.Right().Type().IsInteger() { + base.Errorf("non-integer %s index %v", why, n.Right()) break } - if !n.Bounded() && ir.IsConst(n.Right, constant.Int) { - x := n.Right.Val() + if !n.Bounded() && ir.IsConst(n.Right(), constant.Int) { + x := n.Right().Val() if constant.Sign(x) < 0 { - base.Errorf("invalid %s index %v (index must be non-negative)", why, n.Right) + base.Errorf("invalid %s index %v (index must be non-negative)", why, n.Right()) } else if t.IsArray() && constant.Compare(x, token.GEQ, constant.MakeInt64(t.NumElem())) { - base.Errorf("invalid array index %v (out of bounds for %d-element array)", n.Right, t.NumElem()) - } else if ir.IsConst(n.Left, constant.String) && constant.Compare(x, token.GEQ, constant.MakeInt64(int64(len(n.Left.StringVal())))) { - base.Errorf("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(n.Left.StringVal())) + base.Errorf("invalid array index %v (out of bounds for %d-element array)", n.Right(), t.NumElem()) + } else if ir.IsConst(n.Left(), constant.String) && constant.Compare(x, token.GEQ, constant.MakeInt64(int64(len(n.Left().StringVal())))) { + base.Errorf("invalid string index %v (out of bounds for %d-byte string)", n.Right(), len(n.Left().StringVal())) } else if doesoverflow(x, types.Types[types.TINT]) { - base.Errorf("invalid %s index %v (index too large)", why, n.Right) + base.Errorf("invalid %s index %v (index too large)", why, n.Right()) } } case types.TMAP: - n.Right = assignconv(n.Right, t.Key(), "map index") - n.Type = t.Elem() - n.Op = ir.OINDEXMAP + n.SetRight(assignconv(n.Right(), t.Key(), "map index")) + n.SetType(t.Elem()) + n.SetOp(ir.OINDEXMAP) n.ResetAux() } case ir.ORECV: ok |= ctxStmt | ctxExpr - n.Left = typecheck(n.Left, ctxExpr) - n.Left = defaultlit(n.Left, nil) - l := n.Left - t := l.Type + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetLeft(defaultlit(n.Left(), nil)) + l := n.Left() + t := l.Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } if !t.IsChan() { base.Errorf("invalid operation: %v (receive from non-chan type %v)", n, t) - n.Type = nil + n.SetType(nil) return n } if !t.ChanDir().CanRecv() { base.Errorf("invalid operation: %v (receive from send-only type %v)", n, t) - n.Type = nil + n.SetType(nil) return n } - n.Type = t.Elem() + n.SetType(t.Elem()) case ir.OSEND: ok |= ctxStmt - n.Left = typecheck(n.Left, ctxExpr) - n.Right = typecheck(n.Right, ctxExpr) - n.Left = defaultlit(n.Left, nil) - t := n.Left.Type + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetRight(typecheck(n.Right(), ctxExpr)) + n.SetLeft(defaultlit(n.Left(), nil)) + t := n.Left().Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } if !t.IsChan() { base.Errorf("invalid operation: %v (send to non-chan type %v)", n, t) - n.Type = nil + n.SetType(nil) return n } if !t.ChanDir().CanSend() { base.Errorf("invalid operation: %v (send to receive-only type %v)", n, t) - n.Type = nil + n.SetType(nil) return n } - n.Right = assignconv(n.Right, t.Elem(), "send") - if n.Right.Type == nil { - n.Type = nil + n.SetRight(assignconv(n.Right(), t.Elem(), "send")) + if n.Right().Type() == nil { + n.SetType(nil) return n } - n.Type = nil + n.SetType(nil) case ir.OSLICEHEADER: // Errors here are Fatalf instead of Errorf because only the compiler @@ -1128,26 +1128,26 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { // have already been typechecked in e.g. OMAKESLICE earlier. ok |= ctxExpr - t := n.Type + t := n.Type() if t == nil { base.Fatalf("no type specified for OSLICEHEADER") } if !t.IsSlice() { - base.Fatalf("invalid type %v for OSLICEHEADER", n.Type) + base.Fatalf("invalid type %v for OSLICEHEADER", n.Type()) } - if n.Left == nil || n.Left.Type == nil || !n.Left.Type.IsUnsafePtr() { + if n.Left() == nil || n.Left().Type() == nil || !n.Left().Type().IsUnsafePtr() { base.Fatalf("need unsafe.Pointer for OSLICEHEADER") } - if x := n.List.Len(); x != 2 { + if x := n.List().Len(); x != 2 { base.Fatalf("expected 2 params (len, cap) for OSLICEHEADER, got %d", x) } - n.Left = typecheck(n.Left, ctxExpr) - l := typecheck(n.List.First(), ctxExpr) - c := typecheck(n.List.Second(), ctxExpr) + n.SetLeft(typecheck(n.Left(), ctxExpr)) + l := typecheck(n.List().First(), ctxExpr) + c := typecheck(n.List().Second(), ctxExpr) l = defaultlit(l, types.Types[types.TINT]) c = defaultlit(c, types.Types[types.TINT]) @@ -1163,8 +1163,8 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { base.Fatalf("len larger than cap for OSLICEHEADER") } - n.List.SetFirst(l) - n.List.SetSecond(c) + n.List().SetFirst(l) + n.List().SetSecond(c) case ir.OMAKESLICECOPY: // Errors here are Fatalf instead of Errorf because only the compiler @@ -1173,145 +1173,145 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { // have already been typechecked in OMAKE and OCOPY earlier. ok |= ctxExpr - t := n.Type + t := n.Type() if t == nil { base.Fatalf("no type specified for OMAKESLICECOPY") } if !t.IsSlice() { - base.Fatalf("invalid type %v for OMAKESLICECOPY", n.Type) + base.Fatalf("invalid type %v for OMAKESLICECOPY", n.Type()) } - if n.Left == nil { + if n.Left() == nil { base.Fatalf("missing len argument for OMAKESLICECOPY") } - if n.Right == nil { + if n.Right() == nil { base.Fatalf("missing slice argument to copy for OMAKESLICECOPY") } - n.Left = typecheck(n.Left, ctxExpr) - n.Right = typecheck(n.Right, ctxExpr) + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetRight(typecheck(n.Right(), ctxExpr)) - n.Left = defaultlit(n.Left, types.Types[types.TINT]) + n.SetLeft(defaultlit(n.Left(), types.Types[types.TINT])) - if !n.Left.Type.IsInteger() && n.Type.Etype != types.TIDEAL { + if !n.Left().Type().IsInteger() && n.Type().Etype != types.TIDEAL { base.Errorf("non-integer len argument in OMAKESLICECOPY") } - if ir.IsConst(n.Left, constant.Int) { - if doesoverflow(n.Left.Val(), types.Types[types.TINT]) { + if ir.IsConst(n.Left(), constant.Int) { + if doesoverflow(n.Left().Val(), types.Types[types.TINT]) { base.Fatalf("len for OMAKESLICECOPY too large") } - if constant.Sign(n.Left.Val()) < 0 { + if constant.Sign(n.Left().Val()) < 0 { base.Fatalf("len for OMAKESLICECOPY must be non-negative") } } case ir.OSLICE, ir.OSLICE3: ok |= ctxExpr - n.Left = typecheck(n.Left, ctxExpr) + n.SetLeft(typecheck(n.Left(), ctxExpr)) low, high, max := n.SliceBounds() - hasmax := n.Op.IsSlice3() + hasmax := n.Op().IsSlice3() low = typecheck(low, ctxExpr) high = typecheck(high, ctxExpr) max = typecheck(max, ctxExpr) - n.Left = defaultlit(n.Left, nil) + n.SetLeft(defaultlit(n.Left(), nil)) low = indexlit(low) high = indexlit(high) max = indexlit(max) n.SetSliceBounds(low, high, max) - l := n.Left - if l.Type == nil { - n.Type = nil + l := n.Left() + if l.Type() == nil { + n.SetType(nil) return n } - if l.Type.IsArray() { - if !islvalue(n.Left) { + if l.Type().IsArray() { + if !islvalue(n.Left()) { base.Errorf("invalid operation %v (slice of unaddressable value)", n) - n.Type = nil + n.SetType(nil) return n } - n.Left = ir.Nod(ir.OADDR, n.Left, nil) - n.Left.SetImplicit(true) - n.Left = typecheck(n.Left, ctxExpr) - l = n.Left + n.SetLeft(ir.Nod(ir.OADDR, n.Left(), nil)) + n.Left().SetImplicit(true) + n.SetLeft(typecheck(n.Left(), ctxExpr)) + l = n.Left() } - t := l.Type + t := l.Type() var tp *types.Type if t.IsString() { if hasmax { base.Errorf("invalid operation %v (3-index slice of string)", n) - n.Type = nil + n.SetType(nil) return n } - n.Type = t - n.Op = ir.OSLICESTR + n.SetType(t) + n.SetOp(ir.OSLICESTR) } else if t.IsPtr() && t.Elem().IsArray() { tp = t.Elem() - n.Type = types.NewSlice(tp.Elem()) - dowidth(n.Type) + n.SetType(types.NewSlice(tp.Elem())) + dowidth(n.Type()) if hasmax { - n.Op = ir.OSLICE3ARR + n.SetOp(ir.OSLICE3ARR) } else { - n.Op = ir.OSLICEARR + n.SetOp(ir.OSLICEARR) } } else if t.IsSlice() { - n.Type = t + n.SetType(t) } else { base.Errorf("cannot slice %v (type %v)", l, t) - n.Type = nil + n.SetType(nil) return n } if low != nil && !checksliceindex(l, low, tp) { - n.Type = nil + n.SetType(nil) return n } if high != nil && !checksliceindex(l, high, tp) { - n.Type = nil + n.SetType(nil) return n } if max != nil && !checksliceindex(l, max, tp) { - n.Type = nil + n.SetType(nil) return n } if !checksliceconst(low, high) || !checksliceconst(low, max) || !checksliceconst(high, max) { - n.Type = nil + n.SetType(nil) return n } // call and call like case ir.OCALL: - typecheckslice(n.Ninit.Slice(), ctxStmt) // imported rewritten f(g()) calls (#30907) - n.Left = typecheck(n.Left, ctxExpr|ctxType|ctxCallee) - if n.Left.Diag() { + typecheckslice(n.Init().Slice(), ctxStmt) // imported rewritten f(g()) calls (#30907) + n.SetLeft(typecheck(n.Left(), ctxExpr|ctxType|ctxCallee)) + if n.Left().Diag() { n.SetDiag(true) } - l := n.Left + l := n.Left() - if l.Op == ir.ONAME && l.SubOp() != 0 { + if l.Op() == ir.ONAME && l.SubOp() != 0 { if n.IsDDD() && l.SubOp() != ir.OAPPEND { base.Errorf("invalid use of ... with builtin %v", l) } // builtin: OLEN, OCAP, etc. - n.Op = l.SubOp() - n.Left = n.Right - n.Right = nil + n.SetOp(l.SubOp()) + n.SetLeft(n.Right()) + n.SetRight(nil) n = typecheck1(n, top) return n } - n.Left = defaultlit(n.Left, nil) - l = n.Left - if l.Op == ir.OTYPE { + n.SetLeft(defaultlit(n.Left(), nil)) + l = n.Left() + if l.Op() == ir.OTYPE { if n.IsDDD() { - if !l.Type.Broke() { - base.Errorf("invalid use of ... in type conversion to %v", l.Type) + if !l.Type().Broke() { + base.Errorf("invalid use of ... in type conversion to %v", l.Type()) } n.SetDiag(true) } @@ -1320,12 +1320,12 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { ok |= ctxExpr // turn CALL(type, arg) into CONV(arg) w/ type - n.Left = nil + n.SetLeft(nil) - n.Op = ir.OCONV - n.Type = l.Type - if !onearg(n, "conversion to %v", l.Type) { - n.Type = nil + n.SetOp(ir.OCONV) + n.SetType(l.Type()) + if !onearg(n, "conversion to %v", l.Type()) { + n.SetType(nil) return n } n = typecheck1(n, top) @@ -1333,19 +1333,19 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { } typecheckargs(n) - t := l.Type + t := l.Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } checkwidth(t) - switch l.Op { + switch l.Op() { case ir.ODOTINTER: - n.Op = ir.OCALLINTER + n.SetOp(ir.OCALLINTER) case ir.ODOTMETH: - n.Op = ir.OCALLMETH + n.SetOp(ir.OCALLMETH) // typecheckaste was used here but there wasn't enough // information further down the call chain to know if we @@ -1353,44 +1353,44 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { // It isn't necessary, so just do a sanity check. tp := t.Recv().Type - if l.Left == nil || !types.Identical(l.Left.Type, tp) { + if l.Left() == nil || !types.Identical(l.Left().Type(), tp) { base.Fatalf("method receiver") } default: - n.Op = ir.OCALLFUNC + n.SetOp(ir.OCALLFUNC) if t.Etype != types.TFUNC { name := l.String() - if isBuiltinFuncName(name) && l.Name.Defn != nil { + if isBuiltinFuncName(name) && l.Name().Defn != nil { // be more specific when the function // name matches a predeclared function base.Errorf("cannot call non-function %s (type %v), declared at %s", - name, t, base.FmtPos(l.Name.Defn.Pos)) + name, t, base.FmtPos(l.Name().Defn.Pos())) } else { base.Errorf("cannot call non-function %s (type %v)", name, t) } - n.Type = nil + n.SetType(nil) return n } } - typecheckaste(ir.OCALL, n.Left, n.IsDDD(), t.Params(), n.List, func() string { return fmt.Sprintf("argument to %v", n.Left) }) + typecheckaste(ir.OCALL, n.Left(), n.IsDDD(), t.Params(), n.List(), func() string { return fmt.Sprintf("argument to %v", n.Left()) }) ok |= ctxStmt if t.NumResults() == 0 { break } ok |= ctxExpr if t.NumResults() == 1 { - n.Type = l.Type.Results().Field(0).Type + n.SetType(l.Type().Results().Field(0).Type) - if n.Op == ir.OCALLFUNC && n.Left.Op == ir.ONAME && isRuntimePkg(n.Left.Sym.Pkg) && n.Left.Sym.Name == "getg" { + if n.Op() == ir.OCALLFUNC && n.Left().Op() == ir.ONAME && isRuntimePkg(n.Left().Sym().Pkg) && n.Left().Sym().Name == "getg" { // Emit code for runtime.getg() directly instead of calling function. // Most such rewrites (for example the similar one for math.Sqrt) should be done in walk, // so that the ordering pass can make sure to preserve the semantics of the original code // (in particular, the exact time of the function call) by introducing temporaries. // In this case, we know getg() always returns the same result within a given function // and we want to avoid the temporaries, so we do the rewrite earlier than is typical. - n.Op = ir.OGETG + n.SetOp(ir.OGETG) } break @@ -1402,73 +1402,73 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { break } - n.Type = l.Type.Results() + n.SetType(l.Type().Results()) case ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF: ok |= ctxExpr - if !onearg(n, "%v", n.Op) { - n.Type = nil + if !onearg(n, "%v", n.Op()) { + n.SetType(nil) return n } - n.Type = types.Types[types.TUINTPTR] + n.SetType(types.Types[types.TUINTPTR]) case ir.OCAP, ir.OLEN: ok |= ctxExpr - if !onearg(n, "%v", n.Op) { - n.Type = nil + if !onearg(n, "%v", n.Op()) { + n.SetType(nil) return n } - n.Left = typecheck(n.Left, ctxExpr) - n.Left = defaultlit(n.Left, nil) - n.Left = implicitstar(n.Left) - l := n.Left - t := l.Type + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetLeft(defaultlit(n.Left(), nil)) + n.SetLeft(implicitstar(n.Left())) + l := n.Left() + t := l.Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } var ok bool - if n.Op == ir.OLEN { + if n.Op() == ir.OLEN { ok = okforlen[t.Etype] } else { ok = okforcap[t.Etype] } if !ok { - base.Errorf("invalid argument %L for %v", l, n.Op) - n.Type = nil + base.Errorf("invalid argument %L for %v", l, n.Op()) + n.SetType(nil) return n } - n.Type = types.Types[types.TINT] + n.SetType(types.Types[types.TINT]) case ir.OREAL, ir.OIMAG: ok |= ctxExpr - if !onearg(n, "%v", n.Op) { - n.Type = nil + if !onearg(n, "%v", n.Op()) { + n.SetType(nil) return n } - n.Left = typecheck(n.Left, ctxExpr) - l := n.Left - t := l.Type + n.SetLeft(typecheck(n.Left(), ctxExpr)) + l := n.Left() + t := l.Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } // Determine result type. switch t.Etype { case types.TIDEAL: - n.Type = types.UntypedFloat + n.SetType(types.UntypedFloat) case types.TCOMPLEX64: - n.Type = types.Types[types.TFLOAT32] + n.SetType(types.Types[types.TFLOAT32]) case types.TCOMPLEX128: - n.Type = types.Types[types.TFLOAT64] + n.SetType(types.Types[types.TFLOAT64]) default: - base.Errorf("invalid argument %L for %v", l, n.Op) - n.Type = nil + base.Errorf("invalid argument %L for %v", l, n.Op()) + n.SetType(nil) return n } @@ -1476,34 +1476,34 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { ok |= ctxExpr typecheckargs(n) if !twoarg(n) { - n.Type = nil + n.SetType(nil) return n } - l := n.Left - r := n.Right - if l.Type == nil || r.Type == nil { - n.Type = nil + l := n.Left() + r := n.Right() + if l.Type() == nil || r.Type() == nil { + n.SetType(nil) return n } l, r = defaultlit2(l, r, false) - if l.Type == nil || r.Type == nil { - n.Type = nil + if l.Type() == nil || r.Type() == nil { + n.SetType(nil) return n } - n.Left = l - n.Right = r + n.SetLeft(l) + n.SetRight(r) - if !types.Identical(l.Type, r.Type) { - base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type) - n.Type = nil + if !types.Identical(l.Type(), r.Type()) { + base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type(), r.Type()) + n.SetType(nil) return n } var t *types.Type - switch l.Type.Etype { + switch l.Type().Etype { default: - base.Errorf("invalid operation: %v (arguments have type %v, expected floating-point)", n, l.Type) - n.Type = nil + base.Errorf("invalid operation: %v (arguments have type %v, expected floating-point)", n, l.Type()) + n.SetType(nil) return n case types.TIDEAL: @@ -1515,30 +1515,30 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { case types.TFLOAT64: t = types.Types[types.TCOMPLEX128] } - n.Type = t + n.SetType(t) case ir.OCLOSE: - if !onearg(n, "%v", n.Op) { - n.Type = nil + if !onearg(n, "%v", n.Op()) { + n.SetType(nil) return n } - n.Left = typecheck(n.Left, ctxExpr) - n.Left = defaultlit(n.Left, nil) - l := n.Left - t := l.Type + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetLeft(defaultlit(n.Left(), nil)) + l := n.Left() + t := l.Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } if !t.IsChan() { base.Errorf("invalid operation: %v (non-chan type %v)", n, t) - n.Type = nil + n.SetType(nil) return n } if !t.ChanDir().CanSend() { base.Errorf("invalid operation: %v (cannot close receive-only channel)", n) - n.Type = nil + n.SetType(nil) return n } @@ -1547,78 +1547,78 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { case ir.ODELETE: ok |= ctxStmt typecheckargs(n) - args := n.List + args := n.List() if args.Len() == 0 { base.Errorf("missing arguments to delete") - n.Type = nil + n.SetType(nil) return n } if args.Len() == 1 { base.Errorf("missing second (key) argument to delete") - n.Type = nil + n.SetType(nil) return n } if args.Len() != 2 { base.Errorf("too many arguments to delete") - n.Type = nil + n.SetType(nil) return n } l := args.First() r := args.Second() - if l.Type != nil && !l.Type.IsMap() { - base.Errorf("first argument to delete must be map; have %L", l.Type) - n.Type = nil + if l.Type() != nil && !l.Type().IsMap() { + base.Errorf("first argument to delete must be map; have %L", l.Type()) + n.SetType(nil) return n } - args.SetSecond(assignconv(r, l.Type.Key(), "delete")) + args.SetSecond(assignconv(r, l.Type().Key(), "delete")) case ir.OAPPEND: ok |= ctxExpr typecheckargs(n) - args := n.List + args := n.List() if args.Len() == 0 { base.Errorf("missing arguments to append") - n.Type = nil + n.SetType(nil) return n } - t := args.First().Type + t := args.First().Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } - n.Type = t + n.SetType(t) if !t.IsSlice() { if ir.IsNil(args.First()) { base.Errorf("first argument to append must be typed slice; have untyped nil") - n.Type = nil + n.SetType(nil) return n } base.Errorf("first argument to append must be slice; have %L", t) - n.Type = nil + n.SetType(nil) return n } if n.IsDDD() { if args.Len() == 1 { base.Errorf("cannot use ... on first argument to append") - n.Type = nil + n.SetType(nil) return n } if args.Len() != 2 { base.Errorf("too many arguments to append") - n.Type = nil + n.SetType(nil) return n } - if t.Elem().IsKind(types.TUINT8) && args.Second().Type.IsString() { + if t.Elem().IsKind(types.TUINT8) && args.Second().Type().IsString() { args.SetSecond(defaultlit(args.Second(), types.Types[types.TSTRING])) break } @@ -1629,90 +1629,90 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { as := args.Slice()[1:] for i, n := range as { - if n.Type == nil { + if n.Type() == nil { continue } as[i] = assignconv(n, t.Elem(), "append") - checkwidth(as[i].Type) // ensure width is calculated for backend + checkwidth(as[i].Type()) // ensure width is calculated for backend } case ir.OCOPY: ok |= ctxStmt | ctxExpr typecheckargs(n) if !twoarg(n) { - n.Type = nil + n.SetType(nil) return n } - n.Type = types.Types[types.TINT] - if n.Left.Type == nil || n.Right.Type == nil { - n.Type = nil + n.SetType(types.Types[types.TINT]) + if n.Left().Type() == nil || n.Right().Type() == nil { + n.SetType(nil) return n } - n.Left = defaultlit(n.Left, nil) - n.Right = defaultlit(n.Right, nil) - if n.Left.Type == nil || n.Right.Type == nil { - n.Type = nil + n.SetLeft(defaultlit(n.Left(), nil)) + n.SetRight(defaultlit(n.Right(), nil)) + if n.Left().Type() == nil || n.Right().Type() == nil { + n.SetType(nil) return n } // copy([]byte, string) - if n.Left.Type.IsSlice() && n.Right.Type.IsString() { - if types.Identical(n.Left.Type.Elem(), types.Bytetype) { + if n.Left().Type().IsSlice() && n.Right().Type().IsString() { + if types.Identical(n.Left().Type().Elem(), types.Bytetype) { break } - base.Errorf("arguments to copy have different element types: %L and string", n.Left.Type) - n.Type = nil + base.Errorf("arguments to copy have different element types: %L and string", n.Left().Type()) + n.SetType(nil) return n } - if !n.Left.Type.IsSlice() || !n.Right.Type.IsSlice() { - if !n.Left.Type.IsSlice() && !n.Right.Type.IsSlice() { - base.Errorf("arguments to copy must be slices; have %L, %L", n.Left.Type, n.Right.Type) - } else if !n.Left.Type.IsSlice() { - base.Errorf("first argument to copy should be slice; have %L", n.Left.Type) + if !n.Left().Type().IsSlice() || !n.Right().Type().IsSlice() { + if !n.Left().Type().IsSlice() && !n.Right().Type().IsSlice() { + base.Errorf("arguments to copy must be slices; have %L, %L", n.Left().Type(), n.Right().Type()) + } else if !n.Left().Type().IsSlice() { + base.Errorf("first argument to copy should be slice; have %L", n.Left().Type()) } else { - base.Errorf("second argument to copy should be slice or string; have %L", n.Right.Type) + base.Errorf("second argument to copy should be slice or string; have %L", n.Right().Type()) } - n.Type = nil + n.SetType(nil) return n } - if !types.Identical(n.Left.Type.Elem(), n.Right.Type.Elem()) { - base.Errorf("arguments to copy have different element types: %L and %L", n.Left.Type, n.Right.Type) - n.Type = nil + if !types.Identical(n.Left().Type().Elem(), n.Right().Type().Elem()) { + base.Errorf("arguments to copy have different element types: %L and %L", n.Left().Type(), n.Right().Type()) + n.SetType(nil) return n } case ir.OCONV: ok |= ctxExpr - checkwidth(n.Type) // ensure width is calculated for backend - n.Left = typecheck(n.Left, ctxExpr) - n.Left = convlit1(n.Left, n.Type, true, nil) - t := n.Left.Type - if t == nil || n.Type == nil { - n.Type = nil - return n - } - op, why := convertop(n.Left.Op == ir.OLITERAL, t, n.Type) - n.Op = op - if n.Op == ir.OXXX { - if !n.Diag() && !n.Type.Broke() && !n.Left.Diag() { - base.Errorf("cannot convert %L to type %v%s", n.Left, n.Type, why) + checkwidth(n.Type()) // ensure width is calculated for backend + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetLeft(convlit1(n.Left(), n.Type(), true, nil)) + t := n.Left().Type() + if t == nil || n.Type() == nil { + n.SetType(nil) + return n + } + op, why := convertop(n.Left().Op() == ir.OLITERAL, t, n.Type()) + n.SetOp(op) + if n.Op() == ir.OXXX { + if !n.Diag() && !n.Type().Broke() && !n.Left().Diag() { + base.Errorf("cannot convert %L to type %v%s", n.Left(), n.Type(), why) n.SetDiag(true) } - n.Op = ir.OCONV - n.Type = nil + n.SetOp(ir.OCONV) + n.SetType(nil) return n } - switch n.Op { + switch n.Op() { case ir.OCONVNOP: - if t.Etype == n.Type.Etype { + if t.Etype == n.Type().Etype { switch t.Etype { case types.TFLOAT32, types.TFLOAT64, types.TCOMPLEX64, types.TCOMPLEX128: // Floating point casts imply rounding and // so the conversion must be kept. - n.Op = ir.OCONV + n.SetOp(ir.OCONV) } } @@ -1722,26 +1722,26 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { break case ir.OSTR2RUNES: - if n.Left.Op == ir.OLITERAL { + if n.Left().Op() == ir.OLITERAL { n = stringtoruneslit(n) } } case ir.OMAKE: ok |= ctxExpr - args := n.List.Slice() + args := n.List().Slice() if len(args) == 0 { base.Errorf("missing argument to make") - n.Type = nil + n.SetType(nil) return n } - n.List.Set(nil) + n.PtrList().Set(nil) l := args[0] l = typecheck(l, ctxType) - t := l.Type + t := l.Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } @@ -1749,13 +1749,13 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { switch t.Etype { default: base.Errorf("cannot make type %v", t) - n.Type = nil + n.SetType(nil) return n case types.TSLICE: if i >= len(args) { base.Errorf("missing len argument to make(%v)", t) - n.Type = nil + n.SetType(nil) return n } @@ -1769,23 +1769,23 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { r = typecheck(r, ctxExpr) } - if l.Type == nil || (r != nil && r.Type == nil) { - n.Type = nil + if l.Type() == nil || (r != nil && r.Type() == nil) { + n.SetType(nil) return n } if !checkmake(t, "len", &l) || r != nil && !checkmake(t, "cap", &r) { - n.Type = nil + n.SetType(nil) return n } if ir.IsConst(l, constant.Int) && r != nil && ir.IsConst(r, constant.Int) && constant.Compare(l.Val(), token.GTR, r.Val()) { base.Errorf("len larger than cap in make(%v)", t) - n.Type = nil + n.SetType(nil) return n } - n.Left = l - n.Right = r - n.Op = ir.OMAKESLICE + n.SetLeft(l) + n.SetRight(r) + n.SetOp(ir.OMAKESLICE) case types.TMAP: if i < len(args) { @@ -1793,19 +1793,19 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { i++ l = typecheck(l, ctxExpr) l = defaultlit(l, types.Types[types.TINT]) - if l.Type == nil { - n.Type = nil + if l.Type() == nil { + n.SetType(nil) return n } if !checkmake(t, "size", &l) { - n.Type = nil + n.SetType(nil) return n } - n.Left = l + n.SetLeft(l) } else { - n.Left = nodintconst(0) + n.SetLeft(nodintconst(0)) } - n.Op = ir.OMAKEMAP + n.SetOp(ir.OMAKEMAP) case types.TCHAN: l = nil @@ -1814,59 +1814,59 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { i++ l = typecheck(l, ctxExpr) l = defaultlit(l, types.Types[types.TINT]) - if l.Type == nil { - n.Type = nil + if l.Type() == nil { + n.SetType(nil) return n } if !checkmake(t, "buffer", &l) { - n.Type = nil + n.SetType(nil) return n } - n.Left = l + n.SetLeft(l) } else { - n.Left = nodintconst(0) + n.SetLeft(nodintconst(0)) } - n.Op = ir.OMAKECHAN + n.SetOp(ir.OMAKECHAN) } if i < len(args) { base.Errorf("too many arguments to make(%v)", t) - n.Op = ir.OMAKE - n.Type = nil + n.SetOp(ir.OMAKE) + n.SetType(nil) return n } - n.Type = t + n.SetType(t) case ir.ONEW: ok |= ctxExpr - args := n.List + args := n.List() if args.Len() == 0 { base.Errorf("missing argument to new") - n.Type = nil + n.SetType(nil) return n } l := args.First() l = typecheck(l, ctxType) - t := l.Type + t := l.Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } if args.Len() > 1 { base.Errorf("too many arguments to new(%v)", t) - n.Type = nil + n.SetType(nil) return n } - n.Left = l - n.Type = types.NewPtr(t) + n.SetLeft(l) + n.SetType(types.NewPtr(t)) case ir.OPRINT, ir.OPRINTN: ok |= ctxStmt typecheckargs(n) - ls := n.List.Slice() + ls := n.List().Slice() for i1, n1 := range ls { // Special case for print: int constant is int64, not int. if ir.IsConst(n1, constant.Int) { @@ -1879,45 +1879,45 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { case ir.OPANIC: ok |= ctxStmt if !onearg(n, "panic") { - n.Type = nil + n.SetType(nil) return n } - n.Left = typecheck(n.Left, ctxExpr) - n.Left = defaultlit(n.Left, types.Types[types.TINTER]) - if n.Left.Type == nil { - n.Type = nil + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetLeft(defaultlit(n.Left(), types.Types[types.TINTER])) + if n.Left().Type() == nil { + n.SetType(nil) return n } case ir.ORECOVER: ok |= ctxExpr | ctxStmt - if n.List.Len() != 0 { + if n.List().Len() != 0 { base.Errorf("too many arguments to recover") - n.Type = nil + n.SetType(nil) return n } - n.Type = types.Types[types.TINTER] + n.SetType(types.Types[types.TINTER]) case ir.OCLOSURE: ok |= ctxExpr typecheckclosure(n, top) - if n.Type == nil { + if n.Type() == nil { return n } case ir.OITAB: ok |= ctxExpr - n.Left = typecheck(n.Left, ctxExpr) - t := n.Left.Type + n.SetLeft(typecheck(n.Left(), ctxExpr)) + t := n.Left().Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } if !t.IsInterface() { base.Fatalf("OITAB of %v", t) } - n.Type = types.NewPtr(types.Types[types.TUINTPTR]) + n.SetType(types.NewPtr(types.Types[types.TUINTPTR])) case ir.OIDATA: // Whoever creates the OIDATA node must know a priori the concrete type at that moment, @@ -1926,19 +1926,19 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { case ir.OSPTR: ok |= ctxExpr - n.Left = typecheck(n.Left, ctxExpr) - t := n.Left.Type + n.SetLeft(typecheck(n.Left(), ctxExpr)) + t := n.Left().Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } if !t.IsSlice() && !t.IsString() { base.Fatalf("OSPTR of %v", t) } if t.IsString() { - n.Type = types.NewPtr(types.Types[types.TUINT8]) + n.SetType(types.NewPtr(types.Types[types.TUINT8])) } else { - n.Type = types.NewPtr(t.Elem()) + n.SetType(types.NewPtr(t.Elem())) } case ir.OCLOSUREVAR: @@ -1946,12 +1946,12 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { case ir.OCFUNC: ok |= ctxExpr - n.Left = typecheck(n.Left, ctxExpr) - n.Type = types.Types[types.TUINTPTR] + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetType(types.Types[types.TUINTPTR]) case ir.OCONVNOP: ok |= ctxExpr - n.Left = typecheck(n.Left, ctxExpr) + n.SetLeft(typecheck(n.Left(), ctxExpr)) // statements case ir.OAS: @@ -1960,8 +1960,8 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { typecheckas(n) // Code that creates temps does not bother to set defn, so do it here. - if n.Left.Op == ir.ONAME && ir.IsAutoTmp(n.Left) { - n.Left.Name.Defn = n + if n.Left().Op() == ir.ONAME && ir.IsAutoTmp(n.Left()) { + n.Left().Name().Defn = n } case ir.OAS2: @@ -1981,72 +1981,72 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { case ir.OLABEL: ok |= ctxStmt decldepth++ - if n.Sym.IsBlank() { + if n.Sym().IsBlank() { // Empty identifier is valid but useless. // Eliminate now to simplify life later. // See issues 7538, 11589, 11593. - n.Op = ir.OEMPTY - n.Left = nil + n.SetOp(ir.OEMPTY) + n.SetLeft(nil) } case ir.ODEFER: ok |= ctxStmt - n.Left = typecheck(n.Left, ctxStmt|ctxExpr) - if !n.Left.Diag() { + n.SetLeft(typecheck(n.Left(), ctxStmt|ctxExpr)) + if !n.Left().Diag() { checkdefergo(n) } case ir.OGO: ok |= ctxStmt - n.Left = typecheck(n.Left, ctxStmt|ctxExpr) + n.SetLeft(typecheck(n.Left(), ctxStmt|ctxExpr)) checkdefergo(n) case ir.OFOR, ir.OFORUNTIL: ok |= ctxStmt - typecheckslice(n.Ninit.Slice(), ctxStmt) + typecheckslice(n.Init().Slice(), ctxStmt) decldepth++ - n.Left = typecheck(n.Left, ctxExpr) - n.Left = defaultlit(n.Left, nil) - if n.Left != nil { - t := n.Left.Type + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetLeft(defaultlit(n.Left(), nil)) + if n.Left() != nil { + t := n.Left().Type() if t != nil && !t.IsBoolean() { - base.Errorf("non-bool %L used as for condition", n.Left) + base.Errorf("non-bool %L used as for condition", n.Left()) } } - n.Right = typecheck(n.Right, ctxStmt) - if n.Op == ir.OFORUNTIL { - typecheckslice(n.List.Slice(), ctxStmt) + n.SetRight(typecheck(n.Right(), ctxStmt)) + if n.Op() == ir.OFORUNTIL { + typecheckslice(n.List().Slice(), ctxStmt) } - typecheckslice(n.Nbody.Slice(), ctxStmt) + typecheckslice(n.Body().Slice(), ctxStmt) decldepth-- case ir.OIF: ok |= ctxStmt - typecheckslice(n.Ninit.Slice(), ctxStmt) - n.Left = typecheck(n.Left, ctxExpr) - n.Left = defaultlit(n.Left, nil) - if n.Left != nil { - t := n.Left.Type + typecheckslice(n.Init().Slice(), ctxStmt) + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetLeft(defaultlit(n.Left(), nil)) + if n.Left() != nil { + t := n.Left().Type() if t != nil && !t.IsBoolean() { - base.Errorf("non-bool %L used as if condition", n.Left) + base.Errorf("non-bool %L used as if condition", n.Left()) } } - typecheckslice(n.Nbody.Slice(), ctxStmt) - typecheckslice(n.Rlist.Slice(), ctxStmt) + typecheckslice(n.Body().Slice(), ctxStmt) + typecheckslice(n.Rlist().Slice(), ctxStmt) case ir.ORETURN: ok |= ctxStmt typecheckargs(n) if Curfn == nil { base.Errorf("return outside function") - n.Type = nil + n.SetType(nil) return n } - if Curfn.Type.FuncType().Outnamed && n.List.Len() == 0 { + if Curfn.Type().FuncType().Outnamed && n.List().Len() == 0 { break } - typecheckaste(ir.ORETURN, nil, false, Curfn.Type.Results(), n.List, func() string { return "return argument" }) + typecheckaste(ir.ORETURN, nil, false, Curfn.Type().Results(), n.List(), func() string { return "return argument" }) case ir.ORETJMP: ok |= ctxStmt @@ -2065,7 +2065,7 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { case ir.OTYPESW: base.Errorf("use of .(type) outside type switch") - n.Type = nil + n.SetType(nil) return n case ir.ODCLFUNC: @@ -2074,16 +2074,16 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { case ir.ODCLCONST: ok |= ctxStmt - n.Left = typecheck(n.Left, ctxExpr) + n.SetLeft(typecheck(n.Left(), ctxExpr)) case ir.ODCLTYPE: ok |= ctxStmt - n.Left = typecheck(n.Left, ctxType) - checkwidth(n.Left.Type) + n.SetLeft(typecheck(n.Left(), ctxType)) + checkwidth(n.Left().Type()) } - t := n.Type - if t != nil && !t.IsFuncArgStruct() && n.Op != ir.OTYPE { + t := n.Type() + if t != nil && !t.IsFuncArgStruct() && n.Op() != ir.OTYPE { switch t.Etype { case types.TFUNC, // might have TANY; wait until it's called types.TANY, types.TFORW, types.TIDEAL, types.TNIL, types.TBLANK: @@ -2095,24 +2095,24 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { } n = evalConst(n) - if n.Op == ir.OTYPE && top&ctxType == 0 { - if !n.Type.Broke() { - base.Errorf("type %v is not an expression", n.Type) + if n.Op() == ir.OTYPE && top&ctxType == 0 { + if !n.Type().Broke() { + base.Errorf("type %v is not an expression", n.Type()) } - n.Type = nil + n.SetType(nil) return n } - if top&(ctxExpr|ctxType) == ctxType && n.Op != ir.OTYPE { + if top&(ctxExpr|ctxType) == ctxType && n.Op() != ir.OTYPE { base.Errorf("%v is not a type", n) - n.Type = nil + n.SetType(nil) return n } // TODO(rsc): simplify if (top&(ctxCallee|ctxExpr|ctxType) != 0) && top&ctxStmt == 0 && ok&(ctxExpr|ctxType|ctxCallee) == 0 { base.Errorf("%v used as value", n) - n.Type = nil + n.SetType(nil) return n } @@ -2122,7 +2122,7 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { n.SetDiag(true) } - n.Type = nil + n.SetType(nil) return n } @@ -2130,13 +2130,13 @@ func typecheck1(n *ir.Node, top int) (res *ir.Node) { } func typecheckargs(n *ir.Node) { - if n.List.Len() != 1 || n.IsDDD() { - typecheckslice(n.List.Slice(), ctxExpr) + if n.List().Len() != 1 || n.IsDDD() { + typecheckslice(n.List().Slice(), ctxExpr) return } - typecheckslice(n.List.Slice(), ctxExpr|ctxMultiOK) - t := n.List.First().Type + typecheckslice(n.List().Slice(), ctxExpr|ctxMultiOK) + t := n.List().First().Type() if t == nil || !t.IsFuncArgStruct() { return } @@ -2144,12 +2144,12 @@ func typecheckargs(n *ir.Node) { // Rewrite f(g()) into t1, t2, ... = g(); f(t1, t2, ...). // Save n as n.Orig for fmt.go. - if n.Orig == n { - n.Orig = ir.SepCopy(n) + if n.Orig() == n { + n.SetOrig(ir.SepCopy(n)) } as := ir.Nod(ir.OAS2, nil, nil) - as.Rlist.AppendNodes(&n.List) + as.PtrRlist().AppendNodes(n.PtrList()) // If we're outside of function context, then this call will // be executed during the generated init function. However, @@ -2162,20 +2162,20 @@ func typecheckargs(n *ir.Node) { } for _, f := range t.FieldSlice() { t := temp(f.Type) - as.Ninit.Append(ir.Nod(ir.ODCL, t, nil)) - as.List.Append(t) - n.List.Append(t) + as.PtrInit().Append(ir.Nod(ir.ODCL, t, nil)) + as.PtrList().Append(t) + n.PtrList().Append(t) } if static { Curfn = nil } as = typecheck(as, ctxStmt) - n.Ninit.Append(as) + n.PtrInit().Append(as) } func checksliceindex(l *ir.Node, r *ir.Node, tp *types.Type) bool { - t := r.Type + t := r.Type() if t == nil { return false } @@ -2184,7 +2184,7 @@ func checksliceindex(l *ir.Node, r *ir.Node, tp *types.Type) bool { return false } - if r.Op == ir.OLITERAL { + if r.Op() == ir.OLITERAL { x := r.Val() if constant.Sign(x) < 0 { base.Errorf("invalid slice index %v (index must be non-negative)", r) @@ -2205,7 +2205,7 @@ func checksliceindex(l *ir.Node, r *ir.Node, tp *types.Type) bool { } func checksliceconst(lo *ir.Node, hi *ir.Node) bool { - if lo != nil && hi != nil && lo.Op == ir.OLITERAL && hi.Op == ir.OLITERAL && constant.Compare(lo.Val(), token.GTR, hi.Val()) { + if lo != nil && hi != nil && lo.Op() == ir.OLITERAL && hi.Op() == ir.OLITERAL && constant.Compare(lo.Val(), token.GTR, hi.Val()) { base.Errorf("invalid slice index: %v > %v", lo, hi) return false } @@ -2215,11 +2215,11 @@ func checksliceconst(lo *ir.Node, hi *ir.Node) bool { func checkdefergo(n *ir.Node) { what := "defer" - if n.Op == ir.OGO { + if n.Op() == ir.OGO { what = "go" } - switch n.Left.Op { + switch n.Left().Op() { // ok case ir.OCALLINTER, ir.OCALLMETH, @@ -2245,16 +2245,16 @@ func checkdefergo(n *ir.Node) { ir.ONEW, ir.OREAL, ir.OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof - if n.Left.Orig != nil && n.Left.Orig.Op == ir.OCONV { + if n.Left().Orig() != nil && n.Left().Orig().Op() == ir.OCONV { break } - base.ErrorfAt(n.Pos, "%s discards result of %v", what, n.Left) + base.ErrorfAt(n.Pos(), "%s discards result of %v", what, n.Left()) return } // type is broken or missing, most likely a method call on a broken type // we will warn about the broken type elsewhere. no need to emit a potentially confusing error - if n.Left.Type == nil || n.Left.Type.Broke() { + if n.Left().Type() == nil || n.Left().Type().Broke() { return } @@ -2262,7 +2262,7 @@ func checkdefergo(n *ir.Node) { // The syntax made sure it was a call, so this must be // a conversion. n.SetDiag(true) - base.ErrorfAt(n.Pos, "%s requires function call, not conversion", what) + base.ErrorfAt(n.Pos(), "%s requires function call, not conversion", what) } } @@ -2270,7 +2270,7 @@ func checkdefergo(n *ir.Node) { // n.Left = implicitstar(n.Left) func implicitstar(n *ir.Node) *ir.Node { // insert implicit * if needed for fixed array - t := n.Type + t := n.Type() if t == nil || !t.IsPtr() { return n } @@ -2288,43 +2288,43 @@ func implicitstar(n *ir.Node) *ir.Node { } func onearg(n *ir.Node, f string, args ...interface{}) bool { - if n.Left != nil { + if n.Left() != nil { return true } - if n.List.Len() == 0 { + if n.List().Len() == 0 { p := fmt.Sprintf(f, args...) base.Errorf("missing argument to %s: %v", p, n) return false } - if n.List.Len() > 1 { + if n.List().Len() > 1 { p := fmt.Sprintf(f, args...) base.Errorf("too many arguments to %s: %v", p, n) - n.Left = n.List.First() - n.List.Set(nil) + n.SetLeft(n.List().First()) + n.PtrList().Set(nil) return false } - n.Left = n.List.First() - n.List.Set(nil) + n.SetLeft(n.List().First()) + n.PtrList().Set(nil) return true } func twoarg(n *ir.Node) bool { - if n.Left != nil { + if n.Left() != nil { return true } - if n.List.Len() != 2 { - if n.List.Len() < 2 { + if n.List().Len() != 2 { + if n.List().Len() < 2 { base.Errorf("not enough arguments in call to %v", n) } else { base.Errorf("too many arguments in call to %v", n) } return false } - n.Left = n.List.First() - n.Right = n.List.Second() - n.List.Set(nil) + n.SetLeft(n.List().First()) + n.SetRight(n.List().Second()) + n.PtrList().Set(nil) return true } @@ -2364,7 +2364,7 @@ func typecheckMethodExpr(n *ir.Node) (res *ir.Node) { defer tracePrint("typecheckMethodExpr", n)(&res) } - t := n.Left.Type + t := n.Left().Type() // Compute the method set for t. var ms *types.Fields @@ -2373,8 +2373,8 @@ func typecheckMethodExpr(n *ir.Node) (res *ir.Node) { } else { mt := methtype(t) if mt == nil { - base.Errorf("%v undefined (type %v has no method %v)", n, t, n.Sym) - n.Type = nil + base.Errorf("%v undefined (type %v has no method %v)", n, t, n.Sym()) + n.SetType(nil) return n } expandmeth(mt) @@ -2392,7 +2392,7 @@ func typecheckMethodExpr(n *ir.Node) (res *ir.Node) { } } - s := n.Sym + s := n.Sym() m := lookdot1(n, s, t, ms, 0) if m == nil { if lookdot1(n, s, t, ms, 1) != nil { @@ -2402,31 +2402,31 @@ func typecheckMethodExpr(n *ir.Node) (res *ir.Node) { } else { base.Errorf("%v undefined (type %v has no method %v)", n, t, s) } - n.Type = nil + n.SetType(nil) return n } if !isMethodApplicable(t, m) { base.Errorf("invalid method expression %v (needs pointer receiver: (*%v).%S)", n, t, s) - n.Type = nil + n.SetType(nil) return n } - n.Op = ir.OMETHEXPR - if n.Name == nil { - n.Name = new(ir.Name) + n.SetOp(ir.OMETHEXPR) + if n.Name() == nil { + n.SetName(new(ir.Name)) } - n.Right = NewName(n.Sym) - n.Sym = methodSym(t, n.Sym) - n.Type = methodfunc(m.Type, n.Left.Type) - n.Xoffset = 0 + n.SetRight(NewName(n.Sym())) + n.SetSym(methodSym(t, n.Sym())) + n.SetType(methodfunc(m.Type, n.Left().Type())) + n.SetOffset(0) n.SetClass(ir.PFUNC) n.SetOpt(m) // methodSym already marked n.Sym as a function. // Issue 25065. Make sure that we emit the symbol for a local method. if base.Ctxt.Flag_dynlink && !inimport && (t.Sym == nil || t.Sym.Pkg == ir.LocalPkg) { - makefuncsym(n.Sym) + makefuncsym(n.Sym()) } return n @@ -2448,7 +2448,7 @@ func derefall(t *types.Type) *types.Type { } func lookdot(n *ir.Node, t *types.Type, dostrcmp int) *types.Field { - s := n.Sym + s := n.Sym() dowidth(t) var f1 *types.Field @@ -2457,7 +2457,7 @@ func lookdot(n *ir.Node, t *types.Type, dostrcmp int) *types.Field { } var f2 *types.Field - if n.Left.Type == t || n.Left.Type.Sym == nil { + if n.Left().Type() == t || n.Left().Type().Sym == nil { mt := methtype(t) if mt != nil { f2 = lookdot1(n, s, mt, mt.Methods(), dostrcmp) @@ -2470,21 +2470,21 @@ func lookdot(n *ir.Node, t *types.Type, dostrcmp int) *types.Field { return f1 } if f2 != nil { - base.Errorf("%v is both field and method", n.Sym) + base.Errorf("%v is both field and method", n.Sym()) } if f1.Offset == types.BADWIDTH { base.Fatalf("lookdot badwidth %v %p", f1, f1) } - n.Xoffset = f1.Offset - n.Type = f1.Type + n.SetOffset(f1.Offset) + n.SetType(f1.Type) if t.IsInterface() { - if n.Left.Type.IsPtr() { - n.Left = ir.Nod(ir.ODEREF, n.Left, nil) // implicitstar - n.Left.SetImplicit(true) - n.Left = typecheck(n.Left, ctxExpr) + if n.Left().Type().IsPtr() { + n.SetLeft(ir.Nod(ir.ODEREF, n.Left(), nil)) // implicitstar + n.Left().SetImplicit(true) + n.SetLeft(typecheck(n.Left(), ctxExpr)) } - n.Op = ir.ODOTINTER + n.SetOp(ir.ODOTINTER) } else { n.SetOpt(f1) } @@ -2497,29 +2497,29 @@ func lookdot(n *ir.Node, t *types.Type, dostrcmp int) *types.Field { // Already in the process of diagnosing an error. return f2 } - tt := n.Left.Type + tt := n.Left().Type() dowidth(tt) rcvr := f2.Type.Recv().Type if !types.Identical(rcvr, tt) { if rcvr.IsPtr() && types.Identical(rcvr.Elem(), tt) { - checklvalue(n.Left, "call pointer method on") - n.Left = ir.Nod(ir.OADDR, n.Left, nil) - n.Left.SetImplicit(true) - n.Left = typecheck(n.Left, ctxType|ctxExpr) + checklvalue(n.Left(), "call pointer method on") + n.SetLeft(ir.Nod(ir.OADDR, n.Left(), nil)) + n.Left().SetImplicit(true) + n.SetLeft(typecheck(n.Left(), ctxType|ctxExpr)) } else if tt.IsPtr() && (!rcvr.IsPtr() || rcvr.IsPtr() && rcvr.Elem().NotInHeap()) && types.Identical(tt.Elem(), rcvr) { - n.Left = ir.Nod(ir.ODEREF, n.Left, nil) - n.Left.SetImplicit(true) - n.Left = typecheck(n.Left, ctxType|ctxExpr) + n.SetLeft(ir.Nod(ir.ODEREF, n.Left(), nil)) + n.Left().SetImplicit(true) + n.SetLeft(typecheck(n.Left(), ctxType|ctxExpr)) } else if tt.IsPtr() && tt.Elem().IsPtr() && types.Identical(derefall(tt), derefall(rcvr)) { - base.Errorf("calling method %v with receiver %L requires explicit dereference", n.Sym, n.Left) + base.Errorf("calling method %v with receiver %L requires explicit dereference", n.Sym(), n.Left()) for tt.IsPtr() { // Stop one level early for method with pointer receiver. if rcvr.IsPtr() && !tt.Elem().IsPtr() { break } - n.Left = ir.Nod(ir.ODEREF, n.Left, nil) - n.Left.SetImplicit(true) - n.Left = typecheck(n.Left, ctxType|ctxExpr) + n.SetLeft(ir.Nod(ir.ODEREF, n.Left(), nil)) + n.Left().SetImplicit(true) + n.SetLeft(typecheck(n.Left(), ctxType|ctxExpr)) tt = tt.Elem() } } else { @@ -2528,22 +2528,22 @@ func lookdot(n *ir.Node, t *types.Type, dostrcmp int) *types.Field { } pll := n - ll := n.Left - for ll.Left != nil && (ll.Op == ir.ODOT || ll.Op == ir.ODOTPTR || ll.Op == ir.ODEREF) { + ll := n.Left() + for ll.Left() != nil && (ll.Op() == ir.ODOT || ll.Op() == ir.ODOTPTR || ll.Op() == ir.ODEREF) { pll = ll - ll = ll.Left + ll = ll.Left() } - if pll.Implicit() && ll.Type.IsPtr() && ll.Type.Sym != nil && ir.AsNode(ll.Type.Sym.Def) != nil && ir.AsNode(ll.Type.Sym.Def).Op == ir.OTYPE { + if pll.Implicit() && ll.Type().IsPtr() && ll.Type().Sym != nil && ir.AsNode(ll.Type().Sym.Def) != nil && ir.AsNode(ll.Type().Sym.Def).Op() == ir.OTYPE { // It is invalid to automatically dereference a named pointer type when selecting a method. // Make n.Left == ll to clarify error message. - n.Left = ll + n.SetLeft(ll) return nil } - n.Sym = methodSym(n.Left.Type, f2.Sym) - n.Xoffset = f2.Offset - n.Type = f2.Type - n.Op = ir.ODOTMETH + n.SetSym(methodSym(n.Left().Type(), f2.Sym)) + n.SetOffset(f2.Offset) + n.SetType(f2.Type) + n.SetOp(ir.ODOTMETH) n.SetOpt(f2) return f2 @@ -2554,7 +2554,7 @@ func lookdot(n *ir.Node, t *types.Type, dostrcmp int) *types.Field { func nokeys(l ir.Nodes) bool { for _, n := range l.Slice() { - if n.Op == ir.OKEY || n.Op == ir.OSTRUCTKEY { + if n.Op() == ir.OKEY || n.Op() == ir.OSTRUCTKEY { return false } } @@ -2625,7 +2625,7 @@ func typecheckaste(op ir.Op, call *ir.Node, isddd bool, tstruct *types.Type, nl } n = nl.Index(i) setlineno(n) - if n.Type != nil { + if n.Type() != nil { nl.SetIndex(i, assignconvfn(n, t, desc)) } return @@ -2635,7 +2635,7 @@ func typecheckaste(op ir.Op, call *ir.Node, isddd bool, tstruct *types.Type, nl for ; i < nl.Len(); i++ { n = nl.Index(i) setlineno(n) - if n.Type != nil { + if n.Type() != nil { nl.SetIndex(i, assignconvfn(n, t.Elem(), desc)) } } @@ -2647,7 +2647,7 @@ func typecheckaste(op ir.Op, call *ir.Node, isddd bool, tstruct *types.Type, nl } n = nl.Index(i) setlineno(n) - if n.Type != nil { + if n.Type() != nil { nl.SetIndex(i, assignconvfn(n, t, desc)) } i++ @@ -2666,13 +2666,13 @@ func typecheckaste(op ir.Op, call *ir.Node, isddd bool, tstruct *types.Type, nl return notenough: - if n == nil || (!n.Diag() && n.Type != nil) { + if n == nil || (!n.Diag() && n.Type() != nil) { details := errorDetails(nl, tstruct, isddd) if call != nil { // call is the expression being called, not the overall call. // Method expressions have the form T.M, and the compiler has // rewritten those to ONAME nodes but left T in Left. - if call.Op == ir.OMETHEXPR { + if call.Op() == ir.OMETHEXPR { base.Errorf("not enough arguments in call to method expression %v%s", call, details) } else { base.Errorf("not enough arguments in call to %v%s", call, details) @@ -2703,7 +2703,7 @@ func errorDetails(nl ir.Nodes, tstruct *types.Type, isddd bool) string { } // If any node has an unknown type, suppress it as well for _, n := range nl.Slice() { - if n.Type == nil { + if n.Type() == nil { return "" } } @@ -2747,7 +2747,7 @@ func fmtSignature(nl ir.Nodes, isddd bool) string { var typeStrings []string for i, n := range nl.Slice() { isdddArg := isddd && i == nl.Len()-1 - typeStrings = append(typeStrings, sigrepr(n.Type, isdddArg)) + typeStrings = append(typeStrings, sigrepr(n.Type(), isdddArg)) } return fmt.Sprintf("(%s)", strings.Join(typeStrings, ", ")) @@ -2775,20 +2775,20 @@ func iscomptype(t *types.Type) bool { // pushtype adds elided type information for composite literals if // appropriate, and returns the resulting expression. func pushtype(n *ir.Node, t *types.Type) *ir.Node { - if n == nil || n.Op != ir.OCOMPLIT || n.Right != nil { + if n == nil || n.Op() != ir.OCOMPLIT || n.Right() != nil { return n } switch { case iscomptype(t): // For T, return T{...}. - n.Right = typenod(t) + n.SetRight(typenod(t)) case t.IsPtr() && iscomptype(t.Elem()): // For *T, return &T{...}. - n.Right = typenod(t.Elem()) + n.SetRight(typenod(t.Elem())) - n = ir.NodAt(n.Pos, ir.OADDR, n, nil) + n = ir.NodAt(n.Pos(), ir.OADDR, n, nil) n.SetImplicit(true) } @@ -2807,90 +2807,90 @@ func typecheckcomplit(n *ir.Node) (res *ir.Node) { base.Pos = lno }() - if n.Right == nil { - base.ErrorfAt(n.Pos, "missing type in composite literal") - n.Type = nil + if n.Right() == nil { + base.ErrorfAt(n.Pos(), "missing type in composite literal") + n.SetType(nil) return n } // Save original node (including n.Right) - n.Orig = ir.Copy(n) + n.SetOrig(ir.Copy(n)) - setlineno(n.Right) + setlineno(n.Right()) // Need to handle [...]T arrays specially. - if n.Right.Op == ir.OTARRAY && n.Right.Left != nil && n.Right.Left.Op == ir.ODDD { - n.Right.Right = typecheck(n.Right.Right, ctxType) - if n.Right.Right.Type == nil { - n.Type = nil + if n.Right().Op() == ir.OTARRAY && n.Right().Left() != nil && n.Right().Left().Op() == ir.ODDD { + n.Right().SetRight(typecheck(n.Right().Right(), ctxType)) + if n.Right().Right().Type() == nil { + n.SetType(nil) return n } - elemType := n.Right.Right.Type + elemType := n.Right().Right().Type() - length := typecheckarraylit(elemType, -1, n.List.Slice(), "array literal") + length := typecheckarraylit(elemType, -1, n.List().Slice(), "array literal") - n.Op = ir.OARRAYLIT - n.Type = types.NewArray(elemType, length) - n.Right = nil + n.SetOp(ir.OARRAYLIT) + n.SetType(types.NewArray(elemType, length)) + n.SetRight(nil) return n } - n.Right = typecheck(n.Right, ctxType) - t := n.Right.Type + n.SetRight(typecheck(n.Right(), ctxType)) + t := n.Right().Type() if t == nil { - n.Type = nil + n.SetType(nil) return n } - n.Type = t + n.SetType(t) switch t.Etype { default: base.Errorf("invalid composite literal type %v", t) - n.Type = nil + n.SetType(nil) case types.TARRAY: - typecheckarraylit(t.Elem(), t.NumElem(), n.List.Slice(), "array literal") - n.Op = ir.OARRAYLIT - n.Right = nil + typecheckarraylit(t.Elem(), t.NumElem(), n.List().Slice(), "array literal") + n.SetOp(ir.OARRAYLIT) + n.SetRight(nil) case types.TSLICE: - length := typecheckarraylit(t.Elem(), -1, n.List.Slice(), "slice literal") - n.Op = ir.OSLICELIT - n.Right = nodintconst(length) + length := typecheckarraylit(t.Elem(), -1, n.List().Slice(), "slice literal") + n.SetOp(ir.OSLICELIT) + n.SetRight(nodintconst(length)) case types.TMAP: var cs constSet - for i3, l := range n.List.Slice() { + for i3, l := range n.List().Slice() { setlineno(l) - if l.Op != ir.OKEY { - n.List.SetIndex(i3, typecheck(l, ctxExpr)) + if l.Op() != ir.OKEY { + n.List().SetIndex(i3, typecheck(l, ctxExpr)) base.Errorf("missing key in map literal") continue } - r := l.Left + r := l.Left() r = pushtype(r, t.Key()) r = typecheck(r, ctxExpr) - l.Left = assignconv(r, t.Key(), "map key") - cs.add(base.Pos, l.Left, "key", "map literal") + l.SetLeft(assignconv(r, t.Key(), "map key")) + cs.add(base.Pos, l.Left(), "key", "map literal") - r = l.Right + r = l.Right() r = pushtype(r, t.Elem()) r = typecheck(r, ctxExpr) - l.Right = assignconv(r, t.Elem(), "map value") + l.SetRight(assignconv(r, t.Elem(), "map value")) } - n.Op = ir.OMAPLIT - n.Right = nil + n.SetOp(ir.OMAPLIT) + n.SetRight(nil) case types.TSTRUCT: // Need valid field offsets for Xoffset below. dowidth(t) errored := false - if n.List.Len() != 0 && nokeys(n.List) { + if n.List().Len() != 0 && nokeys(n.List()) { // simple list of variables - ls := n.List.Slice() + ls := n.List().Slice() for i, n1 := range ls { setlineno(n1) n1 = typecheck(n1, ctxExpr) @@ -2911,7 +2911,7 @@ func typecheckcomplit(n *ir.Node) (res *ir.Node) { // No pushtype allowed here. Must name fields for that. n1 = assignconv(n1, f.Type, "field value") n1 = nodSym(ir.OSTRUCTKEY, n1, f.Sym) - n1.Xoffset = f.Offset + n1.SetOffset(f.Offset) ls[i] = n1 } if len(ls) < t.NumFields() { @@ -2921,41 +2921,41 @@ func typecheckcomplit(n *ir.Node) (res *ir.Node) { hash := make(map[string]bool) // keyed list - ls := n.List.Slice() + ls := n.List().Slice() for i, l := range ls { setlineno(l) - if l.Op == ir.OKEY { - key := l.Left + if l.Op() == ir.OKEY { + key := l.Left() - l.Op = ir.OSTRUCTKEY - l.Left = l.Right - l.Right = nil + l.SetOp(ir.OSTRUCTKEY) + l.SetLeft(l.Right()) + l.SetRight(nil) // An OXDOT uses the Sym field to hold // the field to the right of the dot, // so s will be non-nil, but an OXDOT // is never a valid struct literal key. - if key.Sym == nil || key.Op == ir.OXDOT || key.Sym.IsBlank() { + if key.Sym() == nil || key.Op() == ir.OXDOT || key.Sym().IsBlank() { base.Errorf("invalid field name %v in struct initializer", key) - l.Left = typecheck(l.Left, ctxExpr) + l.SetLeft(typecheck(l.Left(), ctxExpr)) continue } // Sym might have resolved to name in other top-level // package, because of import dot. Redirect to correct sym // before we do the lookup. - s := key.Sym + s := key.Sym() if s.Pkg != ir.LocalPkg && types.IsExported(s.Name) { s1 := lookup(s.Name) if s1.Origpkg == s.Pkg { s = s1 } } - l.Sym = s + l.SetSym(s) } - if l.Op != ir.OSTRUCTKEY { + if l.Op() != ir.OSTRUCTKEY { if !errored { base.Errorf("mixture of field:value and value initializers") errored = true @@ -2964,22 +2964,22 @@ func typecheckcomplit(n *ir.Node) (res *ir.Node) { continue } - f := lookdot1(nil, l.Sym, t, t.Fields(), 0) + f := lookdot1(nil, l.Sym(), t, t.Fields(), 0) if f == nil { - if ci := lookdot1(nil, l.Sym, t, t.Fields(), 2); ci != nil { // Case-insensitive lookup. + if ci := lookdot1(nil, l.Sym(), t, t.Fields(), 2); ci != nil { // Case-insensitive lookup. if visible(ci.Sym) { - base.Errorf("unknown field '%v' in struct literal of type %v (but does have %v)", l.Sym, t, ci.Sym) - } else if nonexported(l.Sym) && l.Sym.Name == ci.Sym.Name { // Ensure exactness before the suggestion. - base.Errorf("cannot refer to unexported field '%v' in struct literal of type %v", l.Sym, t) + base.Errorf("unknown field '%v' in struct literal of type %v (but does have %v)", l.Sym(), t, ci.Sym) + } else if nonexported(l.Sym()) && l.Sym().Name == ci.Sym.Name { // Ensure exactness before the suggestion. + base.Errorf("cannot refer to unexported field '%v' in struct literal of type %v", l.Sym(), t) } else { - base.Errorf("unknown field '%v' in struct literal of type %v", l.Sym, t) + base.Errorf("unknown field '%v' in struct literal of type %v", l.Sym(), t) } continue } var f *types.Field - p, _ := dotpath(l.Sym, t, &f, true) + p, _ := dotpath(l.Sym(), t, &f, true) if p == nil || f.IsMethod() { - base.Errorf("unknown field '%v' in struct literal of type %v", l.Sym, t) + base.Errorf("unknown field '%v' in struct literal of type %v", l.Sym(), t) continue } // dotpath returns the parent embedded types in reverse order. @@ -2987,21 +2987,21 @@ func typecheckcomplit(n *ir.Node) (res *ir.Node) { for ei := len(p) - 1; ei >= 0; ei-- { ep = append(ep, p[ei].field.Sym.Name) } - ep = append(ep, l.Sym.Name) + ep = append(ep, l.Sym().Name) base.Errorf("cannot use promoted field %v in struct literal of type %v", strings.Join(ep, "."), t) continue } fielddup(f.Sym.Name, hash) - l.Xoffset = f.Offset + l.SetOffset(f.Offset) // No pushtype allowed here. Tried and rejected. - l.Left = typecheck(l.Left, ctxExpr) - l.Left = assignconv(l.Left, f.Type, "field value") + l.SetLeft(typecheck(l.Left(), ctxExpr)) + l.SetLeft(assignconv(l.Left(), f.Type, "field value")) } } - n.Op = ir.OSTRUCTLIT - n.Right = nil + n.SetOp(ir.OSTRUCTLIT) + n.SetRight(nil) } return n @@ -3013,7 +3013,7 @@ func typecheckarraylit(elemType *types.Type, bound int64, elts []*ir.Node, ctx s // keys so we can check for duplicate indices. var indices map[int64]bool for _, elt := range elts { - if elt.Op == ir.OKEY { + if elt.Op() == ir.OKEY { indices = make(map[int64]bool) break } @@ -3024,29 +3024,29 @@ func typecheckarraylit(elemType *types.Type, bound int64, elts []*ir.Node, ctx s setlineno(elt) r := elts[i] var kv *ir.Node - if elt.Op == ir.OKEY { - elt.Left = typecheck(elt.Left, ctxExpr) - key = indexconst(elt.Left) + if elt.Op() == ir.OKEY { + elt.SetLeft(typecheck(elt.Left(), ctxExpr)) + key = indexconst(elt.Left()) if key < 0 { - if !elt.Left.Diag() { + if !elt.Left().Diag() { if key == -2 { base.Errorf("index too large") } else { base.Errorf("index must be non-negative integer constant") } - elt.Left.SetDiag(true) + elt.Left().SetDiag(true) } key = -(1 << 30) // stay negative for a while } kv = elt - r = elt.Right + r = elt.Right() } r = pushtype(r, elemType) r = typecheck(r, ctxExpr) r = assignconv(r, elemType, ctx) if kv != nil { - kv.Right = r + kv.SetRight(r) } else { elts[i] = r } @@ -3087,12 +3087,12 @@ func nonexported(sym *types.Sym) bool { // lvalue etc func islvalue(n *ir.Node) bool { - switch n.Op { + switch n.Op() { case ir.OINDEX: - if n.Left.Type != nil && n.Left.Type.IsArray() { - return islvalue(n.Left) + if n.Left().Type() != nil && n.Left().Type().IsArray() { + return islvalue(n.Left()) } - if n.Left.Type != nil && n.Left.Type.IsString() { + if n.Left().Type() != nil && n.Left().Type().IsString() { return false } fallthrough @@ -3100,7 +3100,7 @@ func islvalue(n *ir.Node) bool { return true case ir.ODOT: - return islvalue(n.Left) + return islvalue(n.Left()) case ir.ONAME: if n.Class() == ir.PFUNC { @@ -3120,12 +3120,12 @@ func checklvalue(n *ir.Node, verb string) { func checkassign(stmt *ir.Node, n *ir.Node) { // Variables declared in ORANGE are assigned on every iteration. - if n.Name == nil || n.Name.Defn != stmt || stmt.Op == ir.ORANGE { + if n.Name() == nil || n.Name().Defn != stmt || stmt.Op() == ir.ORANGE { r := outervalue(n) - if r.Op == ir.ONAME { - r.Name.SetAssigned(true) - if r.Name.IsClosureVar() { - r.Name.Defn.Name.SetAssigned(true) + if r.Op() == ir.ONAME { + r.Name().SetAssigned(true) + if r.Name().IsClosureVar() { + r.Name().Defn.Name().SetAssigned(true) } } } @@ -3133,27 +3133,27 @@ func checkassign(stmt *ir.Node, n *ir.Node) { if islvalue(n) { return } - if n.Op == ir.OINDEXMAP { + if n.Op() == ir.OINDEXMAP { n.SetIndexMapLValue(true) return } // have already complained about n being invalid - if n.Type == nil { + if n.Type() == nil { return } switch { - case n.Op == ir.ODOT && n.Left.Op == ir.OINDEXMAP: + case n.Op() == ir.ODOT && n.Left().Op() == ir.OINDEXMAP: base.Errorf("cannot assign to struct field %v in map", n) - case (n.Op == ir.OINDEX && n.Left.Type.IsString()) || n.Op == ir.OSLICESTR: + case (n.Op() == ir.OINDEX && n.Left().Type().IsString()) || n.Op() == ir.OSLICESTR: base.Errorf("cannot assign to %v (strings are immutable)", n) - case n.Op == ir.OLITERAL && n.Sym != nil && isGoConst(n): + case n.Op() == ir.OLITERAL && n.Sym() != nil && isGoConst(n): base.Errorf("cannot assign to %v (declared const)", n) default: base.Errorf("cannot assign to %v", n) } - n.Type = nil + n.SetType(nil) } func checkassignlist(stmt *ir.Node, l ir.Nodes) { @@ -3178,29 +3178,29 @@ func checkassignlist(stmt *ir.Node, l ir.Nodes) { // lvalue expression is for OSLICE and OAPPEND optimizations, and it // is correct in those settings. func samesafeexpr(l *ir.Node, r *ir.Node) bool { - if l.Op != r.Op || !types.Identical(l.Type, r.Type) { + if l.Op() != r.Op() || !types.Identical(l.Type(), r.Type()) { return false } - switch l.Op { + switch l.Op() { case ir.ONAME, ir.OCLOSUREVAR: return l == r case ir.ODOT, ir.ODOTPTR: - return l.Sym != nil && r.Sym != nil && l.Sym == r.Sym && samesafeexpr(l.Left, r.Left) + return l.Sym() != nil && r.Sym() != nil && l.Sym() == r.Sym() && samesafeexpr(l.Left(), r.Left()) case ir.ODEREF, ir.OCONVNOP, ir.ONOT, ir.OBITNOT, ir.OPLUS, ir.ONEG: - return samesafeexpr(l.Left, r.Left) + return samesafeexpr(l.Left(), r.Left()) case ir.OCONV: // Some conversions can't be reused, such as []byte(str). // Allow only numeric-ish types. This is a bit conservative. - return issimple[l.Type.Etype] && samesafeexpr(l.Left, r.Left) + return issimple[l.Type().Etype] && samesafeexpr(l.Left(), r.Left()) case ir.OINDEX, ir.OINDEXMAP, ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.OLSH, ir.ORSH, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD: - return samesafeexpr(l.Left, r.Left) && samesafeexpr(l.Right, r.Right) + return samesafeexpr(l.Left(), r.Left()) && samesafeexpr(l.Right(), r.Right()) case ir.OLITERAL: return constant.Compare(l.Val(), token.EQL, r.Val()) @@ -3227,30 +3227,30 @@ func typecheckas(n *ir.Node) { // if the variable has a type (ntype) then typechecking // will not look at defn, so it is okay (and desirable, // so that the conversion below happens). - n.Left = resolve(n.Left) + n.SetLeft(resolve(n.Left())) - if n.Left.Name == nil || n.Left.Name.Defn != n || n.Left.Name.Param.Ntype != nil { - n.Left = typecheck(n.Left, ctxExpr|ctxAssign) + if n.Left().Name() == nil || n.Left().Name().Defn != n || n.Left().Name().Param.Ntype != nil { + n.SetLeft(typecheck(n.Left(), ctxExpr|ctxAssign)) } // Use ctxMultiOK so we can emit an "N variables but M values" error // to be consistent with typecheckas2 (#26616). - n.Right = typecheck(n.Right, ctxExpr|ctxMultiOK) - checkassign(n, n.Left) - if n.Right != nil && n.Right.Type != nil { - if n.Right.Type.IsFuncArgStruct() { - base.Errorf("assignment mismatch: 1 variable but %v returns %d values", n.Right.Left, n.Right.Type.NumFields()) + n.SetRight(typecheck(n.Right(), ctxExpr|ctxMultiOK)) + checkassign(n, n.Left()) + if n.Right() != nil && n.Right().Type() != nil { + if n.Right().Type().IsFuncArgStruct() { + base.Errorf("assignment mismatch: 1 variable but %v returns %d values", n.Right().Left(), n.Right().Type().NumFields()) // Multi-value RHS isn't actually valid for OAS; nil out // to indicate failed typechecking. - n.Right.Type = nil - } else if n.Left.Type != nil { - n.Right = assignconv(n.Right, n.Left.Type, "assignment") + n.Right().SetType(nil) + } else if n.Left().Type() != nil { + n.SetRight(assignconv(n.Right(), n.Left().Type(), "assignment")) } } - if n.Left.Name != nil && n.Left.Name.Defn == n && n.Left.Name.Param.Ntype == nil { - n.Right = defaultlit(n.Right, nil) - n.Left.Type = n.Right.Type + if n.Left().Name() != nil && n.Left().Name().Defn == n && n.Left().Name().Param.Ntype == nil { + n.SetRight(defaultlit(n.Right(), nil)) + n.Left().SetType(n.Right().Type()) } // second half of dance. @@ -3258,16 +3258,16 @@ func typecheckas(n *ir.Node) { // just to get it over with. see dance above. n.SetTypecheck(1) - if n.Left.Typecheck() == 0 { - n.Left = typecheck(n.Left, ctxExpr|ctxAssign) + if n.Left().Typecheck() == 0 { + n.SetLeft(typecheck(n.Left(), ctxExpr|ctxAssign)) } - if !ir.IsBlank(n.Left) { - checkwidth(n.Left.Type) // ensure width is calculated for backend + if !ir.IsBlank(n.Left()) { + checkwidth(n.Left().Type()) // ensure width is calculated for backend } } func checkassignto(src *types.Type, dst *ir.Node) { - if op, why := assignop(src, dst.Type); op == ir.OXXX { + if op, why := assignop(src, dst.Type()); op == ir.OXXX { base.Errorf("cannot assign %v to %L in multiple assignment%s", src, dst, why) return } @@ -3278,73 +3278,73 @@ func typecheckas2(n *ir.Node) { defer tracePrint("typecheckas2", n)(nil) } - ls := n.List.Slice() + ls := n.List().Slice() for i1, n1 := range ls { // delicate little dance. n1 = resolve(n1) ls[i1] = n1 - if n1.Name == nil || n1.Name.Defn != n || n1.Name.Param.Ntype != nil { + if n1.Name() == nil || n1.Name().Defn != n || n1.Name().Param.Ntype != nil { ls[i1] = typecheck(ls[i1], ctxExpr|ctxAssign) } } - cl := n.List.Len() - cr := n.Rlist.Len() + cl := n.List().Len() + cr := n.Rlist().Len() if cl > 1 && cr == 1 { - n.Rlist.SetFirst(typecheck(n.Rlist.First(), ctxExpr|ctxMultiOK)) + n.Rlist().SetFirst(typecheck(n.Rlist().First(), ctxExpr|ctxMultiOK)) } else { - typecheckslice(n.Rlist.Slice(), ctxExpr) + typecheckslice(n.Rlist().Slice(), ctxExpr) } - checkassignlist(n, n.List) + checkassignlist(n, n.List()) var l *ir.Node var r *ir.Node if cl == cr { // easy - ls := n.List.Slice() - rs := n.Rlist.Slice() + ls := n.List().Slice() + rs := n.Rlist().Slice() for il, nl := range ls { nr := rs[il] - if nl.Type != nil && nr.Type != nil { - rs[il] = assignconv(nr, nl.Type, "assignment") + if nl.Type() != nil && nr.Type() != nil { + rs[il] = assignconv(nr, nl.Type(), "assignment") } - if nl.Name != nil && nl.Name.Defn == n && nl.Name.Param.Ntype == nil { + if nl.Name() != nil && nl.Name().Defn == n && nl.Name().Param.Ntype == nil { rs[il] = defaultlit(rs[il], nil) - nl.Type = rs[il].Type + nl.SetType(rs[il].Type()) } } goto out } - l = n.List.First() - r = n.Rlist.First() + l = n.List().First() + r = n.Rlist().First() // x,y,z = f() if cr == 1 { - if r.Type == nil { + if r.Type() == nil { goto out } - switch r.Op { + switch r.Op() { case ir.OCALLMETH, ir.OCALLINTER, ir.OCALLFUNC: - if !r.Type.IsFuncArgStruct() { + if !r.Type().IsFuncArgStruct() { break } - cr = r.Type.NumFields() + cr = r.Type().NumFields() if cr != cl { goto mismatch } - n.Op = ir.OAS2FUNC - n.Right = r - n.Rlist.Set(nil) - for i, l := range n.List.Slice() { - f := r.Type.Field(i) - if f.Type != nil && l.Type != nil { + n.SetOp(ir.OAS2FUNC) + n.SetRight(r) + n.PtrRlist().Set(nil) + for i, l := range n.List().Slice() { + f := r.Type().Field(i) + if f.Type != nil && l.Type() != nil { checkassignto(f.Type, l) } - if l.Name != nil && l.Name.Defn == n && l.Name.Param.Ntype == nil { - l.Type = f.Type + if l.Name() != nil && l.Name().Defn == n && l.Name().Param.Ntype == nil { + l.SetType(f.Type) } } goto out @@ -3353,51 +3353,51 @@ func typecheckas2(n *ir.Node) { // x, ok = y if cl == 2 && cr == 1 { - if r.Type == nil { + if r.Type() == nil { goto out } - switch r.Op { + switch r.Op() { case ir.OINDEXMAP, ir.ORECV, ir.ODOTTYPE: - switch r.Op { + switch r.Op() { case ir.OINDEXMAP: - n.Op = ir.OAS2MAPR + n.SetOp(ir.OAS2MAPR) case ir.ORECV: - n.Op = ir.OAS2RECV + n.SetOp(ir.OAS2RECV) case ir.ODOTTYPE: - n.Op = ir.OAS2DOTTYPE - r.Op = ir.ODOTTYPE2 + n.SetOp(ir.OAS2DOTTYPE) + r.SetOp(ir.ODOTTYPE2) } - n.Right = r - n.Rlist.Set(nil) - if l.Type != nil { - checkassignto(r.Type, l) + n.SetRight(r) + n.PtrRlist().Set(nil) + if l.Type() != nil { + checkassignto(r.Type(), l) } - if l.Name != nil && l.Name.Defn == n { - l.Type = r.Type + if l.Name() != nil && l.Name().Defn == n { + l.SetType(r.Type()) } - l := n.List.Second() - if l.Type != nil && !l.Type.IsBoolean() { + l := n.List().Second() + if l.Type() != nil && !l.Type().IsBoolean() { checkassignto(types.Types[types.TBOOL], l) } - if l.Name != nil && l.Name.Defn == n && l.Name.Param.Ntype == nil { - l.Type = types.Types[types.TBOOL] + if l.Name() != nil && l.Name().Defn == n && l.Name().Param.Ntype == nil { + l.SetType(types.Types[types.TBOOL]) } goto out } } mismatch: - switch r.Op { + switch r.Op() { default: base.Errorf("assignment mismatch: %d variables but %d values", cl, cr) case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER: - base.Errorf("assignment mismatch: %d variables but %v returns %d values", cl, r.Left, cr) + base.Errorf("assignment mismatch: %d variables but %v returns %d values", cl, r.Left(), cr) } // second half of dance out: n.SetTypecheck(1) - ls = n.List.Slice() + ls = n.List().Slice() for i1, n1 := range ls { if n1.Typecheck() == 0 { ls[i1] = typecheck(ls[i1], ctxExpr|ctxAssign) @@ -3411,50 +3411,50 @@ func typecheckfunc(n *ir.Node) { defer tracePrint("typecheckfunc", n)(nil) } - for _, ln := range n.Func.Dcl { - if ln.Op == ir.ONAME && (ln.Class() == ir.PPARAM || ln.Class() == ir.PPARAMOUT) { - ln.Name.Decldepth = 1 + for _, ln := range n.Func().Dcl { + if ln.Op() == ir.ONAME && (ln.Class() == ir.PPARAM || ln.Class() == ir.PPARAMOUT) { + ln.Name().Decldepth = 1 } } - n.Func.Nname = typecheck(n.Func.Nname, ctxExpr|ctxAssign) - t := n.Func.Nname.Type + n.Func().Nname = typecheck(n.Func().Nname, ctxExpr|ctxAssign) + t := n.Func().Nname.Type() if t == nil { return } - n.Type = t + n.SetType(t) rcvr := t.Recv() - if rcvr != nil && n.Func.Shortname != nil { - m := addmethod(n, n.Func.Shortname, t, true, n.Func.Pragma&ir.Nointerface != 0) + if rcvr != nil && n.Func().Shortname != nil { + m := addmethod(n, n.Func().Shortname, t, true, n.Func().Pragma&ir.Nointerface != 0) if m == nil { return } - n.Func.Nname.Sym = methodSym(rcvr.Type, n.Func.Shortname) - declare(n.Func.Nname, ir.PFUNC) + n.Func().Nname.SetSym(methodSym(rcvr.Type, n.Func().Shortname)) + declare(n.Func().Nname, ir.PFUNC) } - if base.Ctxt.Flag_dynlink && !inimport && n.Func.Nname != nil { - makefuncsym(n.Func.Nname.Sym) + if base.Ctxt.Flag_dynlink && !inimport && n.Func().Nname != nil { + makefuncsym(n.Func().Nname.Sym()) } } // The result of stringtoruneslit MUST be assigned back to n, e.g. // n.Left = stringtoruneslit(n.Left) func stringtoruneslit(n *ir.Node) *ir.Node { - if n.Left.Op != ir.OLITERAL || n.Left.Val().Kind() != constant.String { + if n.Left().Op() != ir.OLITERAL || n.Left().Val().Kind() != constant.String { base.Fatalf("stringtoarraylit %v", n) } var l []*ir.Node i := 0 - for _, r := range n.Left.StringVal() { + for _, r := range n.Left().StringVal() { l = append(l, ir.Nod(ir.OKEY, nodintconst(int64(i)), nodintconst(int64(r)))) i++ } - nn := ir.Nod(ir.OCOMPLIT, nil, typenod(n.Type)) - nn.List.Set(l) + nn := ir.Nod(ir.OCOMPLIT, nil, typenod(n.Type())) + nn.PtrList().Set(l) nn = typecheck(nn, ctxExpr) return nn } @@ -3463,9 +3463,9 @@ var mapqueue []*ir.Node func checkMapKeys() { for _, n := range mapqueue { - k := n.Type.MapType().Key + k := n.Type().MapType().Key if !k.Broke() && !IsComparable(k) { - base.ErrorfAt(n.Pos, "invalid map key type %v", k) + base.ErrorfAt(n.Pos(), "invalid map key type %v", k) } } mapqueue = nil @@ -3487,9 +3487,9 @@ func setUnderlying(t, underlying *types.Type) { // Restore unnecessarily clobbered attributes. t.Nod = ir.AsTypesNode(n) - t.Sym = n.Sym - if n.Name != nil { - t.Vargen = n.Name.Vargen + t.Sym = n.Sym() + if n.Name() != nil { + t.Vargen = n.Name().Vargen } t.Cache = cache t.SetDeferwidth(false) @@ -3503,7 +3503,7 @@ func setUnderlying(t, underlying *types.Type) { } // Propagate go:notinheap pragma from the Name to the Type. - if n.Name != nil && n.Name.Param != nil && n.Name.Param.Pragma()&ir.NotInHeap != 0 { + if n.Name() != nil && n.Name().Param != nil && n.Name().Param.Pragma()&ir.NotInHeap != 0 { t.SetNotInHeap(true) } @@ -3526,17 +3526,17 @@ func typecheckdeftype(n *ir.Node) { } n.SetTypecheck(1) - n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, ctxType) - t := n.Name.Param.Ntype.Type + n.Name().Param.Ntype = typecheck(n.Name().Param.Ntype, ctxType) + t := n.Name().Param.Ntype.Type() if t == nil { n.SetDiag(true) - n.Type = nil - } else if n.Type == nil { + n.SetType(nil) + } else if n.Type() == nil { n.SetDiag(true) } else { // copy new type and clear fields // that don't come along. - setUnderlying(n.Type, t) + setUnderlying(n.Type(), t) } } @@ -3547,13 +3547,13 @@ func typecheckdef(n *ir.Node) { lno := setlineno(n) - if n.Op == ir.ONONAME { + if n.Op() == ir.ONONAME { if !n.Diag() { n.SetDiag(true) // Note: adderrorname looks for this string and // adds context about the outer expression - base.ErrorfAt(base.Pos, "undefined: %v", n.Sym) + base.ErrorfAt(base.Pos, "undefined: %v", n.Sym()) } base.Pos = lno return @@ -3570,7 +3570,7 @@ func typecheckdef(n *ir.Node) { fmt.Printf("typecheckdef loop:") for i := len(typecheckdefstack) - 1; i >= 0; i-- { n := typecheckdefstack[i] - fmt.Printf(" %v", n.Sym) + fmt.Printf(" %v", n.Sym()) } fmt.Printf("\n") base.Fatalf("typecheckdef loop") @@ -3578,82 +3578,82 @@ func typecheckdef(n *ir.Node) { n.SetWalkdef(2) - if n.Type != nil || n.Sym == nil { // builtin or no name + if n.Type() != nil || n.Sym() == nil { // builtin or no name goto ret } - switch n.Op { + switch n.Op() { default: - base.Fatalf("typecheckdef %v", n.Op) + base.Fatalf("typecheckdef %v", n.Op()) case ir.OLITERAL: - if n.Name.Param.Ntype != nil { - n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, ctxType) - n.Type = n.Name.Param.Ntype.Type - n.Name.Param.Ntype = nil - if n.Type == nil { + if n.Name().Param.Ntype != nil { + n.Name().Param.Ntype = typecheck(n.Name().Param.Ntype, ctxType) + n.SetType(n.Name().Param.Ntype.Type()) + n.Name().Param.Ntype = nil + if n.Type() == nil { n.SetDiag(true) goto ret } } - e := n.Name.Defn - n.Name.Defn = nil + e := n.Name().Defn + n.Name().Defn = nil if e == nil { ir.Dump("typecheckdef nil defn", n) - base.ErrorfAt(n.Pos, "xxx") + base.ErrorfAt(n.Pos(), "xxx") } e = typecheck(e, ctxExpr) - if e.Type == nil { + if e.Type() == nil { goto ret } if !isGoConst(e) { if !e.Diag() { - if e.Op == ir.ONIL { - base.ErrorfAt(n.Pos, "const initializer cannot be nil") + if e.Op() == ir.ONIL { + base.ErrorfAt(n.Pos(), "const initializer cannot be nil") } else { - base.ErrorfAt(n.Pos, "const initializer %v is not a constant", e) + base.ErrorfAt(n.Pos(), "const initializer %v is not a constant", e) } e.SetDiag(true) } goto ret } - t := n.Type + t := n.Type() if t != nil { if !ir.OKForConst[t.Etype] { - base.ErrorfAt(n.Pos, "invalid constant type %v", t) + base.ErrorfAt(n.Pos(), "invalid constant type %v", t) goto ret } - if !e.Type.IsUntyped() && !types.Identical(t, e.Type) { - base.ErrorfAt(n.Pos, "cannot use %L as type %v in const initializer", e, t) + if !e.Type().IsUntyped() && !types.Identical(t, e.Type()) { + base.ErrorfAt(n.Pos(), "cannot use %L as type %v in const initializer", e, t) goto ret } e = convlit(e, t) } - n.Type = e.Type - if n.Type != nil { + n.SetType(e.Type()) + if n.Type() != nil { n.SetVal(e.Val()) } case ir.ONAME: - if n.Name.Param.Ntype != nil { - n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, ctxType) - n.Type = n.Name.Param.Ntype.Type - if n.Type == nil { + if n.Name().Param.Ntype != nil { + n.Name().Param.Ntype = typecheck(n.Name().Param.Ntype, ctxType) + n.SetType(n.Name().Param.Ntype.Type()) + if n.Type() == nil { n.SetDiag(true) goto ret } } - if n.Type != nil { + if n.Type() != nil { break } - if n.Name.Defn == nil { + if n.Name().Defn == nil { if n.SubOp() != 0 { // like OPRINTN break } @@ -3665,33 +3665,33 @@ func typecheckdef(n *ir.Node) { break } - base.Fatalf("var without type, init: %v", n.Sym) + base.Fatalf("var without type, init: %v", n.Sym()) } - if n.Name.Defn.Op == ir.ONAME { - n.Name.Defn = typecheck(n.Name.Defn, ctxExpr) - n.Type = n.Name.Defn.Type + if n.Name().Defn.Op() == ir.ONAME { + n.Name().Defn = typecheck(n.Name().Defn, ctxExpr) + n.SetType(n.Name().Defn.Type()) break } - n.Name.Defn = typecheck(n.Name.Defn, ctxStmt) // fills in n.Type + n.Name().Defn = typecheck(n.Name().Defn, ctxStmt) // fills in n.Type case ir.OTYPE: - if p := n.Name.Param; p.Alias() { + if p := n.Name().Param; p.Alias() { // Type alias declaration: Simply use the rhs type - no need // to create a new type. // If we have a syntax error, p.Ntype may be nil. if p.Ntype != nil { p.Ntype = typecheck(p.Ntype, ctxType) - n.Type = p.Ntype.Type - if n.Type == nil { + n.SetType(p.Ntype.Type()) + if n.Type() == nil { n.SetDiag(true) goto ret } // For package-level type aliases, set n.Sym.Def so we can identify // it as a type alias during export. See also #31959. - if n.Name.Curfn == nil { - n.Sym.Def = ir.AsTypesNode(p.Ntype) + if n.Name().Curfn == nil { + n.Sym().Def = ir.AsTypesNode(p.Ntype) } } break @@ -3701,20 +3701,20 @@ func typecheckdef(n *ir.Node) { defercheckwidth() n.SetWalkdef(1) setTypeNode(n, types.New(types.TFORW)) - n.Type.Sym = n.Sym + n.Type().Sym = n.Sym() errorsBefore := base.Errors() typecheckdeftype(n) - if n.Type.Etype == types.TFORW && base.Errors() > errorsBefore { + if n.Type().Etype == types.TFORW && base.Errors() > errorsBefore { // Something went wrong during type-checking, // but it was reported. Silence future errors. - n.Type.SetBroke(true) + n.Type().SetBroke(true) } resumecheckwidth() } ret: - if n.Op != ir.OLITERAL && n.Type != nil && n.Type.IsUntyped() { - base.Fatalf("got %v for %v", n.Type, n) + if n.Op() != ir.OLITERAL && n.Type() != nil && n.Type().IsUntyped() { + base.Fatalf("got %v for %v", n.Type(), n) } last := len(typecheckdefstack) - 1 if typecheckdefstack[last] != n { @@ -3729,14 +3729,14 @@ ret: func checkmake(t *types.Type, arg string, np **ir.Node) bool { n := *np - if !n.Type.IsInteger() && n.Type.Etype != types.TIDEAL { - base.Errorf("non-integer %s argument in make(%v) - %v", arg, t, n.Type) + if !n.Type().IsInteger() && n.Type().Etype != types.TIDEAL { + base.Errorf("non-integer %s argument in make(%v) - %v", arg, t, n.Type()) return false } // Do range checks for constants before defaultlit // to avoid redundant "constant NNN overflows int" errors. - if n.Op == ir.OLITERAL { + if n.Op() == ir.OLITERAL { v := toint(n.Val()) if constant.Sign(v) < 0 { base.Errorf("negative %s argument in make(%v)", arg, t) @@ -3764,14 +3764,14 @@ func markbreak(n *ir.Node, implicit *ir.Node) { return } - switch n.Op { + switch n.Op() { case ir.OBREAK: - if n.Sym == nil { + if n.Sym() == nil { if implicit != nil { implicit.SetHasBreak(true) } } else { - lab := ir.AsNode(n.Sym.Label) + lab := ir.AsNode(n.Sym().Label) if lab != nil { lab.SetHasBreak(true) } @@ -3780,12 +3780,12 @@ func markbreak(n *ir.Node, implicit *ir.Node) { implicit = n fallthrough default: - markbreak(n.Left, implicit) - markbreak(n.Right, implicit) - markbreaklist(n.Ninit, implicit) - markbreaklist(n.Nbody, implicit) - markbreaklist(n.List, implicit) - markbreaklist(n.Rlist, implicit) + markbreak(n.Left(), implicit) + markbreak(n.Right(), implicit) + markbreaklist(n.Init(), implicit) + markbreaklist(n.Body(), implicit) + markbreaklist(n.List(), implicit) + markbreaklist(n.Rlist(), implicit) } } @@ -3796,12 +3796,12 @@ func markbreaklist(l ir.Nodes, implicit *ir.Node) { if n == nil { continue } - if n.Op == ir.OLABEL && i+1 < len(s) && n.Name.Defn == s[i+1] { - switch n.Name.Defn.Op { + if n.Op() == ir.OLABEL && i+1 < len(s) && n.Name().Defn == s[i+1] { + switch n.Name().Defn.Op() { case ir.OFOR, ir.OFORUNTIL, ir.OSWITCH, ir.OTYPESW, ir.OSELECT, ir.ORANGE: - n.Sym.Label = ir.AsTypesNode(n.Name.Defn) - markbreak(n.Name.Defn, n.Name.Defn) - n.Sym.Label = nil + n.Sym().Label = ir.AsTypesNode(n.Name().Defn) + markbreak(n.Name().Defn, n.Name().Defn) + n.Sym().Label = nil i++ continue } @@ -3824,20 +3824,20 @@ func isTermNodes(l ir.Nodes) bool { // Isterminating reports whether the node n, the last one in a // statement list, is a terminating statement. func isTermNode(n *ir.Node) bool { - switch n.Op { + switch n.Op() { // NOTE: OLABEL is treated as a separate statement, // not a separate prefix, so skipping to the last statement // in the block handles the labeled statement case by // skipping over the label. No case OLABEL here. case ir.OBLOCK: - return isTermNodes(n.List) + return isTermNodes(n.List()) case ir.OGOTO, ir.ORETURN, ir.ORETJMP, ir.OPANIC, ir.OFALL: return true case ir.OFOR, ir.OFORUNTIL: - if n.Left != nil { + if n.Left() != nil { return false } if n.HasBreak() { @@ -3846,23 +3846,23 @@ func isTermNode(n *ir.Node) bool { return true case ir.OIF: - return isTermNodes(n.Nbody) && isTermNodes(n.Rlist) + return isTermNodes(n.Body()) && isTermNodes(n.Rlist()) case ir.OSWITCH, ir.OTYPESW, ir.OSELECT: if n.HasBreak() { return false } def := false - for _, n1 := range n.List.Slice() { - if !isTermNodes(n1.Nbody) { + for _, n1 := range n.List().Slice() { + if !isTermNodes(n1.Body()) { return false } - if n1.List.Len() == 0 { // default + if n1.List().Len() == 0 { // default def = true } } - if n.Op != ir.OSELECT && !def { + if n.Op() != ir.OSELECT && !def { return false } return true @@ -3873,35 +3873,35 @@ func isTermNode(n *ir.Node) bool { // checkreturn makes sure that fn terminates appropriately. func checkreturn(fn *ir.Node) { - if fn.Type.NumResults() != 0 && fn.Nbody.Len() != 0 { - markbreaklist(fn.Nbody, nil) - if !isTermNodes(fn.Nbody) { - base.ErrorfAt(fn.Func.Endlineno, "missing return at end of function") + if fn.Type().NumResults() != 0 && fn.Body().Len() != 0 { + markbreaklist(fn.Body(), nil) + if !isTermNodes(fn.Body()) { + base.ErrorfAt(fn.Func().Endlineno, "missing return at end of function") } } } func deadcode(fn *ir.Node) { - deadcodeslice(&fn.Nbody) + deadcodeslice(fn.PtrBody()) deadcodefn(fn) } func deadcodefn(fn *ir.Node) { - if fn.Nbody.Len() == 0 { + if fn.Body().Len() == 0 { return } - for _, n := range fn.Nbody.Slice() { - if n.Ninit.Len() > 0 { + for _, n := range fn.Body().Slice() { + if n.Init().Len() > 0 { return } - switch n.Op { + switch n.Op() { case ir.OIF: - if !ir.IsConst(n.Left, constant.Bool) || n.Nbody.Len() > 0 || n.Rlist.Len() > 0 { + if !ir.IsConst(n.Left(), constant.Bool) || n.Body().Len() > 0 || n.Rlist().Len() > 0 { return } case ir.OFOR: - if !ir.IsConst(n.Left, constant.Bool) || n.Left.BoolVal() { + if !ir.IsConst(n.Left(), constant.Bool) || n.Left().BoolVal() { return } default: @@ -3909,13 +3909,13 @@ func deadcodefn(fn *ir.Node) { } } - fn.Nbody.Set([]*ir.Node{ir.Nod(ir.OEMPTY, nil, nil)}) + fn.PtrBody().Set([]*ir.Node{ir.Nod(ir.OEMPTY, nil, nil)}) } func deadcodeslice(nn *ir.Nodes) { var lastLabel = -1 for i, n := range nn.Slice() { - if n != nil && n.Op == ir.OLABEL { + if n != nil && n.Op() == ir.OLABEL { lastLabel = i } } @@ -3927,16 +3927,16 @@ func deadcodeslice(nn *ir.Nodes) { if n == nil { continue } - if n.Op == ir.OIF { - n.Left = deadcodeexpr(n.Left) - if ir.IsConst(n.Left, constant.Bool) { + if n.Op() == ir.OIF { + n.SetLeft(deadcodeexpr(n.Left())) + if ir.IsConst(n.Left(), constant.Bool) { var body ir.Nodes - if n.Left.BoolVal() { - n.Rlist = ir.Nodes{} - body = n.Nbody + if n.Left().BoolVal() { + n.SetRlist(ir.Nodes{}) + body = n.Body() } else { - n.Nbody = ir.Nodes{} - body = n.Rlist + n.SetBody(ir.Nodes{}) + body = n.Rlist() } // If "then" or "else" branch ends with panic or return statement, // it is safe to remove all statements after this node. @@ -3944,7 +3944,7 @@ func deadcodeslice(nn *ir.Nodes) { // We must be careful not to deadcode-remove labels, as they // might be the target of a goto. See issue 28616. if body := body.Slice(); len(body) != 0 { - switch body[(len(body) - 1)].Op { + switch body[(len(body) - 1)].Op() { case ir.ORETURN, ir.ORETJMP, ir.OPANIC: if i > lastLabel { cut = true @@ -3954,10 +3954,10 @@ func deadcodeslice(nn *ir.Nodes) { } } - deadcodeslice(&n.Ninit) - deadcodeslice(&n.Nbody) - deadcodeslice(&n.List) - deadcodeslice(&n.Rlist) + deadcodeslice(n.PtrInit()) + deadcodeslice(n.PtrBody()) + deadcodeslice(n.PtrList()) + deadcodeslice(n.PtrRlist()) if cut { nn.Set(nn.Slice()[:i+1]) break @@ -3969,25 +3969,25 @@ func deadcodeexpr(n *ir.Node) *ir.Node { // Perform dead-code elimination on short-circuited boolean // expressions involving constants with the intent of // producing a constant 'if' condition. - switch n.Op { + switch n.Op() { case ir.OANDAND: - n.Left = deadcodeexpr(n.Left) - n.Right = deadcodeexpr(n.Right) - if ir.IsConst(n.Left, constant.Bool) { - if n.Left.BoolVal() { - return n.Right // true && x => x + n.SetLeft(deadcodeexpr(n.Left())) + n.SetRight(deadcodeexpr(n.Right())) + if ir.IsConst(n.Left(), constant.Bool) { + if n.Left().BoolVal() { + return n.Right() // true && x => x } else { - return n.Left // false && x => false + return n.Left() // false && x => false } } case ir.OOROR: - n.Left = deadcodeexpr(n.Left) - n.Right = deadcodeexpr(n.Right) - if ir.IsConst(n.Left, constant.Bool) { - if n.Left.BoolVal() { - return n.Left // true || x => true + n.SetLeft(deadcodeexpr(n.Left())) + n.SetRight(deadcodeexpr(n.Right())) + if ir.IsConst(n.Left(), constant.Bool) { + if n.Left().BoolVal() { + return n.Left() // true || x => true } else { - return n.Right // false || x => x + return n.Right() // false || x => x } } } @@ -3996,16 +3996,16 @@ func deadcodeexpr(n *ir.Node) *ir.Node { // setTypeNode sets n to an OTYPE node representing t. func setTypeNode(n *ir.Node, t *types.Type) { - n.Op = ir.OTYPE - n.Type = t - n.Type.Nod = ir.AsTypesNode(n) + n.SetOp(ir.OTYPE) + n.SetType(t) + n.Type().Nod = ir.AsTypesNode(n) } // getIotaValue returns the current value for "iota", // or -1 if not within a ConstSpec. func getIotaValue() int64 { if i := len(typecheckdefstack); i > 0 { - if x := typecheckdefstack[i-1]; x.Op == ir.OLITERAL { + if x := typecheckdefstack[i-1]; x.Op() == ir.OLITERAL { return x.Iota() } } @@ -4027,8 +4027,8 @@ func curpkg() *types.Pkg { // TODO(mdempsky): Standardize on either ODCLFUNC or ONAME for // Curfn, rather than mixing them. - if fn.Op == ir.ODCLFUNC { - fn = fn.Func.Nname + if fn.Op() == ir.ODCLFUNC { + fn = fn.Func().Nname } return fnpkg(fn) @@ -4043,12 +4043,12 @@ func methodExprName(n *ir.Node) *ir.Node { // MethodFunc is like MethodName, but returns the types.Field instead. func methodExprFunc(n *ir.Node) *types.Field { - switch n.Op { + switch n.Op() { case ir.ODOTMETH, ir.OMETHEXPR: return n.Opt().(*types.Field) case ir.OCALLPART: return callpartMethod(n) } - base.Fatalf("unexpected node: %v (%v)", n, n.Op) + base.Fatalf("unexpected node: %v (%v)", n, n.Op()) panic("unreachable") } diff --git a/src/cmd/compile/internal/gc/universe.go b/src/cmd/compile/internal/gc/universe.go index bf31055dcc..be22b7e9db 100644 --- a/src/cmd/compile/internal/gc/universe.go +++ b/src/cmd/compile/internal/gc/universe.go @@ -110,7 +110,7 @@ func lexinit() { types.Types[etype] = t } s2.Def = ir.AsTypesNode(typenod(t)) - ir.AsNode(s2.Def).Name = new(ir.Name) + ir.AsNode(s2.Def).SetName(new(ir.Name)) } for _, s := range &builtinFuncs { @@ -131,39 +131,39 @@ func lexinit() { s := ir.BuiltinPkg.Lookup("true") s.Def = ir.AsTypesNode(nodbool(true)) - ir.AsNode(s.Def).Sym = lookup("true") - ir.AsNode(s.Def).Name = new(ir.Name) - ir.AsNode(s.Def).Type = types.UntypedBool + ir.AsNode(s.Def).SetSym(lookup("true")) + ir.AsNode(s.Def).SetName(new(ir.Name)) + ir.AsNode(s.Def).SetType(types.UntypedBool) s = ir.BuiltinPkg.Lookup("false") s.Def = ir.AsTypesNode(nodbool(false)) - ir.AsNode(s.Def).Sym = lookup("false") - ir.AsNode(s.Def).Name = new(ir.Name) - ir.AsNode(s.Def).Type = types.UntypedBool + ir.AsNode(s.Def).SetSym(lookup("false")) + ir.AsNode(s.Def).SetName(new(ir.Name)) + ir.AsNode(s.Def).SetType(types.UntypedBool) s = lookup("_") s.Block = -100 s.Def = ir.AsTypesNode(NewName(s)) types.Types[types.TBLANK] = types.New(types.TBLANK) - ir.AsNode(s.Def).Type = types.Types[types.TBLANK] + ir.AsNode(s.Def).SetType(types.Types[types.TBLANK]) ir.BlankNode = ir.AsNode(s.Def) s = ir.BuiltinPkg.Lookup("_") s.Block = -100 s.Def = ir.AsTypesNode(NewName(s)) types.Types[types.TBLANK] = types.New(types.TBLANK) - ir.AsNode(s.Def).Type = types.Types[types.TBLANK] + ir.AsNode(s.Def).SetType(types.Types[types.TBLANK]) types.Types[types.TNIL] = types.New(types.TNIL) s = ir.BuiltinPkg.Lookup("nil") s.Def = ir.AsTypesNode(nodnil()) - ir.AsNode(s.Def).Sym = s - ir.AsNode(s.Def).Name = new(ir.Name) + ir.AsNode(s.Def).SetSym(s) + ir.AsNode(s.Def).SetName(new(ir.Name)) s = ir.BuiltinPkg.Lookup("iota") s.Def = ir.AsTypesNode(ir.Nod(ir.OIOTA, nil, nil)) - ir.AsNode(s.Def).Sym = s - ir.AsNode(s.Def).Name = new(ir.Name) + ir.AsNode(s.Def).SetSym(s) + ir.AsNode(s.Def).SetName(new(ir.Name)) } func typeinit() { @@ -182,7 +182,7 @@ func typeinit() { types.Types[types.TUNSAFEPTR] = t t.Sym = unsafepkg.Lookup("Pointer") t.Sym.Def = ir.AsTypesNode(typenod(t)) - ir.AsNode(t.Sym.Def).Name = new(ir.Name) + ir.AsNode(t.Sym.Def).SetName(new(ir.Name)) dowidth(types.Types[types.TUNSAFEPTR]) for et := types.TINT8; et <= types.TUINT64; et++ { @@ -359,7 +359,7 @@ func lexinit1() { types.Bytetype = types.New(types.TUINT8) types.Bytetype.Sym = s s.Def = ir.AsTypesNode(typenod(types.Bytetype)) - ir.AsNode(s.Def).Name = new(ir.Name) + ir.AsNode(s.Def).SetName(new(ir.Name)) dowidth(types.Bytetype) // rune alias @@ -367,7 +367,7 @@ func lexinit1() { types.Runetype = types.New(types.TINT32) types.Runetype.Sym = s s.Def = ir.AsTypesNode(typenod(types.Runetype)) - ir.AsNode(s.Def).Name = new(ir.Name) + ir.AsNode(s.Def).SetName(new(ir.Name)) dowidth(types.Runetype) // backend-dependent builtin types (e.g. int). @@ -385,7 +385,7 @@ func lexinit1() { t.Sym = s1 types.Types[s.etype] = t s1.Def = ir.AsTypesNode(typenod(t)) - ir.AsNode(s1.Def).Name = new(ir.Name) + ir.AsNode(s1.Def).SetName(new(ir.Name)) s1.Origpkg = ir.BuiltinPkg dowidth(t) @@ -412,7 +412,7 @@ func finishUniverse() { } nodfp = NewName(lookup(".fp")) - nodfp.Type = types.Types[types.TINT32] + nodfp.SetType(types.Types[types.TINT32]) nodfp.SetClass(ir.PPARAM) - nodfp.Name.SetUsed(true) + nodfp.Name().SetUsed(true) } diff --git a/src/cmd/compile/internal/gc/unsafe.go b/src/cmd/compile/internal/gc/unsafe.go index fce79a6319..c9b0dbcf2f 100644 --- a/src/cmd/compile/internal/gc/unsafe.go +++ b/src/cmd/compile/internal/gc/unsafe.go @@ -11,23 +11,23 @@ import ( // evalunsafe evaluates a package unsafe operation and returns the result. func evalunsafe(n *ir.Node) int64 { - switch n.Op { + switch n.Op() { case ir.OALIGNOF, ir.OSIZEOF: - n.Left = typecheck(n.Left, ctxExpr) - n.Left = defaultlit(n.Left, nil) - tr := n.Left.Type + n.SetLeft(typecheck(n.Left(), ctxExpr)) + n.SetLeft(defaultlit(n.Left(), nil)) + tr := n.Left().Type() if tr == nil { return 0 } dowidth(tr) - if n.Op == ir.OALIGNOF { + if n.Op() == ir.OALIGNOF { return int64(tr.Align) } return tr.Width case ir.OOFFSETOF: // must be a selector. - if n.Left.Op != ir.OXDOT { + if n.Left().Op() != ir.OXDOT { base.Errorf("invalid expression %v", n) return 0 } @@ -35,14 +35,14 @@ func evalunsafe(n *ir.Node) int64 { // Remember base of selector to find it back after dot insertion. // Since r->left may be mutated by typechecking, check it explicitly // first to track it correctly. - n.Left.Left = typecheck(n.Left.Left, ctxExpr) - sbase := n.Left.Left + n.Left().SetLeft(typecheck(n.Left().Left(), ctxExpr)) + sbase := n.Left().Left() - n.Left = typecheck(n.Left, ctxExpr) - if n.Left.Type == nil { + n.SetLeft(typecheck(n.Left(), ctxExpr)) + if n.Left().Type() == nil { return 0 } - switch n.Left.Op { + switch n.Left().Op() { case ir.ODOT, ir.ODOTPTR: break case ir.OCALLPART: @@ -55,27 +55,27 @@ func evalunsafe(n *ir.Node) int64 { // Sum offsets for dots until we reach sbase. var v int64 - for r := n.Left; r != sbase; r = r.Left { - switch r.Op { + for r := n.Left(); r != sbase; r = r.Left() { + switch r.Op() { case ir.ODOTPTR: // For Offsetof(s.f), s may itself be a pointer, // but accessing f must not otherwise involve // indirection via embedded pointer types. - if r.Left != sbase { - base.Errorf("invalid expression %v: selector implies indirection of embedded %v", n, r.Left) + if r.Left() != sbase { + base.Errorf("invalid expression %v: selector implies indirection of embedded %v", n, r.Left()) return 0 } fallthrough case ir.ODOT: - v += r.Xoffset + v += r.Offset() default: - ir.Dump("unsafenmagic", n.Left) - base.Fatalf("impossible %#v node after dot insertion", r.Op) + ir.Dump("unsafenmagic", n.Left()) + base.Fatalf("impossible %#v node after dot insertion", r.Op()) } } return v } - base.Fatalf("unexpected op %v", n.Op) + base.Fatalf("unexpected op %v", n.Op()) return 0 } diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 619a413b9e..77cf59bde8 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -27,39 +27,39 @@ func walk(fn *ir.Node) { errorsBefore := base.Errors() if base.Flag.W != 0 { - s := fmt.Sprintf("\nbefore walk %v", Curfn.Func.Nname.Sym) - ir.DumpList(s, Curfn.Nbody) + s := fmt.Sprintf("\nbefore walk %v", Curfn.Func().Nname.Sym()) + ir.DumpList(s, Curfn.Body()) } lno := base.Pos // Final typecheck for any unused variables. - for i, ln := range fn.Func.Dcl { - if ln.Op == ir.ONAME && (ln.Class() == ir.PAUTO || ln.Class() == ir.PAUTOHEAP) { + for i, ln := range fn.Func().Dcl { + if ln.Op() == ir.ONAME && (ln.Class() == ir.PAUTO || ln.Class() == ir.PAUTOHEAP) { ln = typecheck(ln, ctxExpr|ctxAssign) - fn.Func.Dcl[i] = ln + fn.Func().Dcl[i] = ln } } // Propagate the used flag for typeswitch variables up to the NONAME in its definition. - for _, ln := range fn.Func.Dcl { - if ln.Op == ir.ONAME && (ln.Class() == ir.PAUTO || ln.Class() == ir.PAUTOHEAP) && ln.Name.Defn != nil && ln.Name.Defn.Op == ir.OTYPESW && ln.Name.Used() { - ln.Name.Defn.Left.Name.SetUsed(true) + for _, ln := range fn.Func().Dcl { + if ln.Op() == ir.ONAME && (ln.Class() == ir.PAUTO || ln.Class() == ir.PAUTOHEAP) && ln.Name().Defn != nil && ln.Name().Defn.Op() == ir.OTYPESW && ln.Name().Used() { + ln.Name().Defn.Left().Name().SetUsed(true) } } - for _, ln := range fn.Func.Dcl { - if ln.Op != ir.ONAME || (ln.Class() != ir.PAUTO && ln.Class() != ir.PAUTOHEAP) || ln.Sym.Name[0] == '&' || ln.Name.Used() { + for _, ln := range fn.Func().Dcl { + if ln.Op() != ir.ONAME || (ln.Class() != ir.PAUTO && ln.Class() != ir.PAUTOHEAP) || ln.Sym().Name[0] == '&' || ln.Name().Used() { continue } - if defn := ln.Name.Defn; defn != nil && defn.Op == ir.OTYPESW { - if defn.Left.Name.Used() { + if defn := ln.Name().Defn; defn != nil && defn.Op() == ir.OTYPESW { + if defn.Left().Name().Used() { continue } - base.ErrorfAt(defn.Left.Pos, "%v declared but not used", ln.Sym) - defn.Left.Name.SetUsed(true) // suppress repeats + base.ErrorfAt(defn.Left().Pos(), "%v declared but not used", ln.Sym()) + defn.Left().Name().SetUsed(true) // suppress repeats } else { - base.ErrorfAt(ln.Pos, "%v declared but not used", ln.Sym) + base.ErrorfAt(ln.Pos(), "%v declared but not used", ln.Sym()) } } @@ -67,17 +67,17 @@ func walk(fn *ir.Node) { if base.Errors() > errorsBefore { return } - walkstmtlist(Curfn.Nbody.Slice()) + walkstmtlist(Curfn.Body().Slice()) if base.Flag.W != 0 { - s := fmt.Sprintf("after walk %v", Curfn.Func.Nname.Sym) - ir.DumpList(s, Curfn.Nbody) + s := fmt.Sprintf("after walk %v", Curfn.Func().Nname.Sym()) + ir.DumpList(s, Curfn.Body()) } zeroResults() heapmoves() - if base.Flag.W != 0 && Curfn.Func.Enter.Len() > 0 { - s := fmt.Sprintf("enter %v", Curfn.Func.Nname.Sym) - ir.DumpList(s, Curfn.Func.Enter) + if base.Flag.W != 0 && Curfn.Func().Enter.Len() > 0 { + s := fmt.Sprintf("enter %v", Curfn.Func().Nname.Sym()) + ir.DumpList(s, Curfn.Func().Enter) } } @@ -88,10 +88,10 @@ func walkstmtlist(s []*ir.Node) { } func paramoutheap(fn *ir.Node) bool { - for _, ln := range fn.Func.Dcl { + for _, ln := range fn.Func().Dcl { switch ln.Class() { case ir.PPARAMOUT: - if isParamStackCopy(ln) || ln.Name.Addrtaken() { + if isParamStackCopy(ln) || ln.Name().Addrtaken() { return true } @@ -113,14 +113,14 @@ func walkstmt(n *ir.Node) *ir.Node { setlineno(n) - walkstmtlist(n.Ninit.Slice()) + walkstmtlist(n.Init().Slice()) - switch n.Op { + switch n.Op() { default: - if n.Op == ir.ONAME { - base.Errorf("%v is not a top level statement", n.Sym) + if n.Op() == ir.ONAME { + base.Errorf("%v is not a top level statement", n.Sym()) } else { - base.Errorf("%v is not a top level statement", n.Op) + base.Errorf("%v is not a top level statement", n.Op()) } ir.Dump("nottop", n) @@ -148,13 +148,13 @@ func walkstmt(n *ir.Node) *ir.Node { if n.Typecheck() == 0 { base.Fatalf("missing typecheck: %+v", n) } - wascopy := n.Op == ir.OCOPY - init := n.Ninit - n.Ninit.Set(nil) + wascopy := n.Op() == ir.OCOPY + init := n.Init() + n.PtrInit().Set(nil) n = walkexpr(n, &init) n = addinit(n, init.Slice()) - if wascopy && n.Op == ir.OCONVNOP { - n.Op = ir.OEMPTY // don't leave plain values as statements. + if wascopy && n.Op() == ir.OCONVNOP { + n.SetOp(ir.OEMPTY) // don't leave plain values as statements. } // special case for a receive where we throw away @@ -163,11 +163,11 @@ func walkstmt(n *ir.Node) *ir.Node { if n.Typecheck() == 0 { base.Fatalf("missing typecheck: %+v", n) } - init := n.Ninit - n.Ninit.Set(nil) + init := n.Init() + n.PtrInit().Set(nil) - n.Left = walkexpr(n.Left, &init) - n = mkcall1(chanfn("chanrecv1", 2, n.Left.Type), nil, &init, n.Left, nodnil()) + n.SetLeft(walkexpr(n.Left(), &init)) + n = mkcall1(chanfn("chanrecv1", 2, n.Left().Type()), nil, &init, n.Left(), nodnil()) n = walkexpr(n, &init) n = addinit(n, init.Slice()) @@ -186,138 +186,138 @@ func walkstmt(n *ir.Node) *ir.Node { break case ir.ODCL: - v := n.Left + v := n.Left() if v.Class() == ir.PAUTOHEAP { if base.Flag.CompilingRuntime { base.Errorf("%v escapes to heap, not allowed in runtime", v) } if prealloc[v] == nil { - prealloc[v] = callnew(v.Type) + prealloc[v] = callnew(v.Type()) } - nn := ir.Nod(ir.OAS, v.Name.Param.Heapaddr, prealloc[v]) + nn := ir.Nod(ir.OAS, v.Name().Param.Heapaddr, prealloc[v]) nn.SetColas(true) nn = typecheck(nn, ctxStmt) return walkstmt(nn) } case ir.OBLOCK: - walkstmtlist(n.List.Slice()) + walkstmtlist(n.List().Slice()) case ir.OCASE: base.Errorf("case statement out of place") case ir.ODEFER: - Curfn.Func.SetHasDefer(true) - Curfn.Func.NumDefers++ - if Curfn.Func.NumDefers > maxOpenDefers { + Curfn.Func().SetHasDefer(true) + Curfn.Func().NumDefers++ + if Curfn.Func().NumDefers > maxOpenDefers { // Don't allow open-coded defers if there are more than // 8 defers in the function, since we use a single // byte to record active defers. - Curfn.Func.SetOpenCodedDeferDisallowed(true) + Curfn.Func().SetOpenCodedDeferDisallowed(true) } - if n.Esc != EscNever { + if n.Esc() != EscNever { // If n.Esc is not EscNever, then this defer occurs in a loop, // so open-coded defers cannot be used in this function. - Curfn.Func.SetOpenCodedDeferDisallowed(true) + Curfn.Func().SetOpenCodedDeferDisallowed(true) } fallthrough case ir.OGO: - switch n.Left.Op { + switch n.Left().Op() { case ir.OPRINT, ir.OPRINTN: - n.Left = wrapCall(n.Left, &n.Ninit) + n.SetLeft(wrapCall(n.Left(), n.PtrInit())) case ir.ODELETE: - if mapfast(n.Left.List.First().Type) == mapslow { - n.Left = wrapCall(n.Left, &n.Ninit) + if mapfast(n.Left().List().First().Type()) == mapslow { + n.SetLeft(wrapCall(n.Left(), n.PtrInit())) } else { - n.Left = walkexpr(n.Left, &n.Ninit) + n.SetLeft(walkexpr(n.Left(), n.PtrInit())) } case ir.OCOPY: - n.Left = copyany(n.Left, &n.Ninit, true) + n.SetLeft(copyany(n.Left(), n.PtrInit(), true)) case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER: - if n.Left.Nbody.Len() > 0 { - n.Left = wrapCall(n.Left, &n.Ninit) + if n.Left().Body().Len() > 0 { + n.SetLeft(wrapCall(n.Left(), n.PtrInit())) } else { - n.Left = walkexpr(n.Left, &n.Ninit) + n.SetLeft(walkexpr(n.Left(), n.PtrInit())) } default: - n.Left = walkexpr(n.Left, &n.Ninit) + n.SetLeft(walkexpr(n.Left(), n.PtrInit())) } case ir.OFOR, ir.OFORUNTIL: - if n.Left != nil { - walkstmtlist(n.Left.Ninit.Slice()) - init := n.Left.Ninit - n.Left.Ninit.Set(nil) - n.Left = walkexpr(n.Left, &init) - n.Left = addinit(n.Left, init.Slice()) + if n.Left() != nil { + walkstmtlist(n.Left().Init().Slice()) + init := n.Left().Init() + n.Left().PtrInit().Set(nil) + n.SetLeft(walkexpr(n.Left(), &init)) + n.SetLeft(addinit(n.Left(), init.Slice())) } - n.Right = walkstmt(n.Right) - if n.Op == ir.OFORUNTIL { - walkstmtlist(n.List.Slice()) + n.SetRight(walkstmt(n.Right())) + if n.Op() == ir.OFORUNTIL { + walkstmtlist(n.List().Slice()) } - walkstmtlist(n.Nbody.Slice()) + walkstmtlist(n.Body().Slice()) case ir.OIF: - n.Left = walkexpr(n.Left, &n.Ninit) - walkstmtlist(n.Nbody.Slice()) - walkstmtlist(n.Rlist.Slice()) + n.SetLeft(walkexpr(n.Left(), n.PtrInit())) + walkstmtlist(n.Body().Slice()) + walkstmtlist(n.Rlist().Slice()) case ir.ORETURN: - Curfn.Func.NumReturns++ - if n.List.Len() == 0 { + Curfn.Func().NumReturns++ + if n.List().Len() == 0 { break } - if (Curfn.Type.FuncType().Outnamed && n.List.Len() > 1) || paramoutheap(Curfn) { + if (Curfn.Type().FuncType().Outnamed && n.List().Len() > 1) || paramoutheap(Curfn) { // assign to the function out parameters, // so that reorder3 can fix up conflicts var rl []*ir.Node - for _, ln := range Curfn.Func.Dcl { + for _, ln := range Curfn.Func().Dcl { cl := ln.Class() if cl == ir.PAUTO || cl == ir.PAUTOHEAP { break } if cl == ir.PPARAMOUT { if isParamStackCopy(ln) { - ln = walkexpr(typecheck(ir.Nod(ir.ODEREF, ln.Name.Param.Heapaddr, nil), ctxExpr), nil) + ln = walkexpr(typecheck(ir.Nod(ir.ODEREF, ln.Name().Param.Heapaddr, nil), ctxExpr), nil) } rl = append(rl, ln) } } - if got, want := n.List.Len(), len(rl); got != want { + if got, want := n.List().Len(), len(rl); got != want { // order should have rewritten multi-value function calls // with explicit OAS2FUNC nodes. base.Fatalf("expected %v return arguments, have %v", want, got) } // move function calls out, to make reorder3's job easier. - walkexprlistsafe(n.List.Slice(), &n.Ninit) + walkexprlistsafe(n.List().Slice(), n.PtrInit()) - ll := ascompatee(n.Op, rl, n.List.Slice(), &n.Ninit) - n.List.Set(reorder3(ll)) + ll := ascompatee(n.Op(), rl, n.List().Slice(), n.PtrInit()) + n.PtrList().Set(reorder3(ll)) break } - walkexprlist(n.List.Slice(), &n.Ninit) + walkexprlist(n.List().Slice(), n.PtrInit()) // For each return parameter (lhs), assign the corresponding result (rhs). - lhs := Curfn.Type.Results() - rhs := n.List.Slice() + lhs := Curfn.Type().Results() + rhs := n.List().Slice() res := make([]*ir.Node, lhs.NumFields()) for i, nl := range lhs.FieldSlice() { nname := ir.AsNode(nl.Nname) if isParamHeapCopy(nname) { - nname = nname.Name.Param.Stackcopy + nname = nname.Name().Param.Stackcopy } a := ir.Nod(ir.OAS, nname, rhs[i]) - res[i] = convas(a, &n.Ninit) + res[i] = convas(a, n.PtrInit()) } - n.List.Set(res) + n.PtrList().Set(res) case ir.ORETJMP: break @@ -335,7 +335,7 @@ func walkstmt(n *ir.Node) *ir.Node { n = walkrange(n) } - if n.Op == ir.ONAME { + if n.Op() == ir.ONAME { base.Fatalf("walkstmt ended up with name: %+v", n) } return n @@ -419,24 +419,24 @@ func walkexpr(n *ir.Node, init *ir.Nodes) *ir.Node { } // Eagerly checkwidth all expressions for the back end. - if n.Type != nil && !n.Type.WidthCalculated() { - switch n.Type.Etype { + if n.Type() != nil && !n.Type().WidthCalculated() { + switch n.Type().Etype { case types.TBLANK, types.TNIL, types.TIDEAL: default: - checkwidth(n.Type) + checkwidth(n.Type()) } } - if init == &n.Ninit { + if init == n.PtrInit() { // not okay to use n->ninit when walking n, // because we might replace n with some other node // and would lose the init list. base.Fatalf("walkexpr init == &n->ninit") } - if n.Ninit.Len() != 0 { - walkstmtlist(n.Ninit.Slice()) - init.AppendNodes(&n.Ninit) + if n.Init().Len() != 0 { + walkstmtlist(n.Init().Slice()) + init.AppendNodes(n.PtrInit()) } lno := setlineno(n) @@ -449,20 +449,20 @@ func walkexpr(n *ir.Node, init *ir.Nodes) *ir.Node { base.Fatalf("missed typecheck: %+v", n) } - if n.Type.IsUntyped() { + if n.Type().IsUntyped() { base.Fatalf("expression has untyped type: %+v", n) } - if n.Op == ir.ONAME && n.Class() == ir.PAUTOHEAP { - nn := ir.Nod(ir.ODEREF, n.Name.Param.Heapaddr, nil) + if n.Op() == ir.ONAME && n.Class() == ir.PAUTOHEAP { + nn := ir.Nod(ir.ODEREF, n.Name().Param.Heapaddr, nil) nn = typecheck(nn, ctxExpr) nn = walkexpr(nn, init) - nn.Left.MarkNonNil() + nn.Left().MarkNonNil() return nn } opswitch: - switch n.Op { + switch n.Op() { default: ir.Dump("walk", n) base.Fatalf("walkexpr: switch 1 unknown op %+S", n) @@ -477,134 +477,134 @@ opswitch: case ir.ONOT, ir.ONEG, ir.OPLUS, ir.OBITNOT, ir.OREAL, ir.OIMAG, ir.ODOTMETH, ir.ODOTINTER, ir.ODEREF, ir.OSPTR, ir.OITAB, ir.OIDATA, ir.OADDR: - n.Left = walkexpr(n.Left, init) + n.SetLeft(walkexpr(n.Left(), init)) case ir.OEFACE, ir.OAND, ir.OANDNOT, ir.OSUB, ir.OMUL, ir.OADD, ir.OOR, ir.OXOR, ir.OLSH, ir.ORSH: - n.Left = walkexpr(n.Left, init) - n.Right = walkexpr(n.Right, init) + n.SetLeft(walkexpr(n.Left(), init)) + n.SetRight(walkexpr(n.Right(), init)) case ir.ODOT, ir.ODOTPTR: usefield(n) - n.Left = walkexpr(n.Left, init) + n.SetLeft(walkexpr(n.Left(), init)) case ir.ODOTTYPE, ir.ODOTTYPE2: - n.Left = walkexpr(n.Left, init) + n.SetLeft(walkexpr(n.Left(), init)) // Set up interface type addresses for back end. - n.Right = typename(n.Type) - if n.Op == ir.ODOTTYPE { - n.Right.Right = typename(n.Left.Type) + n.SetRight(typename(n.Type())) + if n.Op() == ir.ODOTTYPE { + n.Right().SetRight(typename(n.Left().Type())) } - if !n.Type.IsInterface() && !n.Left.Type.IsEmptyInterface() { - n.List.Set1(itabname(n.Type, n.Left.Type)) + if !n.Type().IsInterface() && !n.Left().Type().IsEmptyInterface() { + n.PtrList().Set1(itabname(n.Type(), n.Left().Type())) } case ir.OLEN, ir.OCAP: if isRuneCount(n) { // Replace len([]rune(string)) with runtime.countrunes(string). - n = mkcall("countrunes", n.Type, init, conv(n.Left.Left, types.Types[types.TSTRING])) + n = mkcall("countrunes", n.Type(), init, conv(n.Left().Left(), types.Types[types.TSTRING])) break } - n.Left = walkexpr(n.Left, init) + n.SetLeft(walkexpr(n.Left(), init)) // replace len(*[10]int) with 10. // delayed until now to preserve side effects. - t := n.Left.Type + t := n.Left().Type() if t.IsPtr() { t = t.Elem() } if t.IsArray() { - safeexpr(n.Left, init) + safeexpr(n.Left(), init) n = origIntConst(n, t.NumElem()) n.SetTypecheck(1) } case ir.OCOMPLEX: // Use results from call expression as arguments for complex. - if n.Left == nil && n.Right == nil { - n.Left = n.List.First() - n.Right = n.List.Second() + if n.Left() == nil && n.Right() == nil { + n.SetLeft(n.List().First()) + n.SetRight(n.List().Second()) } - n.Left = walkexpr(n.Left, init) - n.Right = walkexpr(n.Right, init) + n.SetLeft(walkexpr(n.Left(), init)) + n.SetRight(walkexpr(n.Right(), init)) case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE: n = walkcompare(n, init) case ir.OANDAND, ir.OOROR: - n.Left = walkexpr(n.Left, init) + n.SetLeft(walkexpr(n.Left(), init)) // cannot put side effects from n.Right on init, // because they cannot run before n.Left is checked. // save elsewhere and store on the eventual n.Right. var ll ir.Nodes - n.Right = walkexpr(n.Right, &ll) - n.Right = addinit(n.Right, ll.Slice()) + n.SetRight(walkexpr(n.Right(), &ll)) + n.SetRight(addinit(n.Right(), ll.Slice())) case ir.OPRINT, ir.OPRINTN: n = walkprint(n, init) case ir.OPANIC: - n = mkcall("gopanic", nil, init, n.Left) + n = mkcall("gopanic", nil, init, n.Left()) case ir.ORECOVER: - n = mkcall("gorecover", n.Type, init, ir.Nod(ir.OADDR, nodfp, nil)) + n = mkcall("gorecover", n.Type(), init, ir.Nod(ir.OADDR, nodfp, nil)) case ir.OCLOSUREVAR, ir.OCFUNC: case ir.OCALLINTER, ir.OCALLFUNC, ir.OCALLMETH: - if n.Op == ir.OCALLINTER { + if n.Op() == ir.OCALLINTER { usemethod(n) markUsedIfaceMethod(n) } - if n.Op == ir.OCALLFUNC && n.Left.Op == ir.OCLOSURE { + if n.Op() == ir.OCALLFUNC && n.Left().Op() == ir.OCLOSURE { // Transform direct call of a closure to call of a normal function. // transformclosure already did all preparation work. // Prepend captured variables to argument list. - n.List.Prepend(n.Left.Func.ClosureEnter.Slice()...) - n.Left.Func.ClosureEnter.Set(nil) + n.PtrList().Prepend(n.Left().Func().ClosureEnter.Slice()...) + n.Left().Func().ClosureEnter.Set(nil) // Replace OCLOSURE with ONAME/PFUNC. - n.Left = n.Left.Func.Nname + n.SetLeft(n.Left().Func().Nname) // Update type of OCALLFUNC node. // Output arguments had not changed, but their offsets could. - if n.Left.Type.NumResults() == 1 { - n.Type = n.Left.Type.Results().Field(0).Type + if n.Left().Type().NumResults() == 1 { + n.SetType(n.Left().Type().Results().Field(0).Type) } else { - n.Type = n.Left.Type.Results() + n.SetType(n.Left().Type().Results()) } } walkCall(n, init) case ir.OAS, ir.OASOP: - init.AppendNodes(&n.Ninit) + init.AppendNodes(n.PtrInit()) // Recognize m[k] = append(m[k], ...) so we can reuse // the mapassign call. - mapAppend := n.Left.Op == ir.OINDEXMAP && n.Right.Op == ir.OAPPEND - if mapAppend && !samesafeexpr(n.Left, n.Right.List.First()) { - base.Fatalf("not same expressions: %v != %v", n.Left, n.Right.List.First()) + mapAppend := n.Left().Op() == ir.OINDEXMAP && n.Right().Op() == ir.OAPPEND + if mapAppend && !samesafeexpr(n.Left(), n.Right().List().First()) { + base.Fatalf("not same expressions: %v != %v", n.Left(), n.Right().List().First()) } - n.Left = walkexpr(n.Left, init) - n.Left = safeexpr(n.Left, init) + n.SetLeft(walkexpr(n.Left(), init)) + n.SetLeft(safeexpr(n.Left(), init)) if mapAppend { - n.Right.List.SetFirst(n.Left) + n.Right().List().SetFirst(n.Left()) } - if n.Op == ir.OASOP { + if n.Op() == ir.OASOP { // Rewrite x op= y into x = x op y. - n.Right = ir.Nod(n.SubOp(), n.Left, n.Right) - n.Right = typecheck(n.Right, ctxExpr) + n.SetRight(ir.Nod(n.SubOp(), n.Left(), n.Right())) + n.SetRight(typecheck(n.Right(), ctxExpr)) - n.Op = ir.OAS + n.SetOp(ir.OAS) n.ResetAux() } @@ -612,35 +612,35 @@ opswitch: break } - if n.Right == nil { + if n.Right() == nil { // TODO(austin): Check all "implicit zeroing" break } - if !instrumenting && isZero(n.Right) { + if !instrumenting && isZero(n.Right()) { break } - switch n.Right.Op { + switch n.Right().Op() { default: - n.Right = walkexpr(n.Right, init) + n.SetRight(walkexpr(n.Right(), init)) case ir.ORECV: // x = <-c; n.Left is x, n.Right.Left is c. // order.stmt made sure x is addressable. - n.Right.Left = walkexpr(n.Right.Left, init) + n.Right().SetLeft(walkexpr(n.Right().Left(), init)) - n1 := ir.Nod(ir.OADDR, n.Left, nil) - r := n.Right.Left // the channel - n = mkcall1(chanfn("chanrecv1", 2, r.Type), nil, init, r, n1) + n1 := ir.Nod(ir.OADDR, n.Left(), nil) + r := n.Right().Left() // the channel + n = mkcall1(chanfn("chanrecv1", 2, r.Type()), nil, init, r, n1) n = walkexpr(n, init) break opswitch case ir.OAPPEND: // x = append(...) - r := n.Right - if r.Type.Elem().NotInHeap() { - base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", r.Type.Elem()) + r := n.Right() + if r.Type().Elem().NotInHeap() { + base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", r.Type().Elem()) } switch { case isAppendOfMake(r): @@ -651,86 +651,86 @@ opswitch: default: r = walkappend(r, init, n) } - n.Right = r - if r.Op == ir.OAPPEND { + n.SetRight(r) + if r.Op() == ir.OAPPEND { // Left in place for back end. // Do not add a new write barrier. // Set up address of type for back end. - r.Left = typename(r.Type.Elem()) + r.SetLeft(typename(r.Type().Elem())) break opswitch } // Otherwise, lowered for race detector. // Treat as ordinary assignment. } - if n.Left != nil && n.Right != nil { + if n.Left() != nil && n.Right() != nil { n = convas(n, init) } case ir.OAS2: - init.AppendNodes(&n.Ninit) - walkexprlistsafe(n.List.Slice(), init) - walkexprlistsafe(n.Rlist.Slice(), init) - ll := ascompatee(ir.OAS, n.List.Slice(), n.Rlist.Slice(), init) + init.AppendNodes(n.PtrInit()) + walkexprlistsafe(n.List().Slice(), init) + walkexprlistsafe(n.Rlist().Slice(), init) + ll := ascompatee(ir.OAS, n.List().Slice(), n.Rlist().Slice(), init) ll = reorder3(ll) n = liststmt(ll) // a,b,... = fn() case ir.OAS2FUNC: - init.AppendNodes(&n.Ninit) + init.AppendNodes(n.PtrInit()) - r := n.Right - walkexprlistsafe(n.List.Slice(), init) + r := n.Right() + walkexprlistsafe(n.List().Slice(), init) r = walkexpr(r, init) if isIntrinsicCall(r) { - n.Right = r + n.SetRight(r) break } init.Append(r) - ll := ascompatet(n.List, r.Type) + ll := ascompatet(n.List(), r.Type()) n = liststmt(ll) // x, y = <-c // order.stmt made sure x is addressable or blank. case ir.OAS2RECV: - init.AppendNodes(&n.Ninit) + init.AppendNodes(n.PtrInit()) - r := n.Right - walkexprlistsafe(n.List.Slice(), init) - r.Left = walkexpr(r.Left, init) + r := n.Right() + walkexprlistsafe(n.List().Slice(), init) + r.SetLeft(walkexpr(r.Left(), init)) var n1 *ir.Node - if ir.IsBlank(n.List.First()) { + if ir.IsBlank(n.List().First()) { n1 = nodnil() } else { - n1 = ir.Nod(ir.OADDR, n.List.First(), nil) + n1 = ir.Nod(ir.OADDR, n.List().First(), nil) } - fn := chanfn("chanrecv2", 2, r.Left.Type) - ok := n.List.Second() - call := mkcall1(fn, types.Types[types.TBOOL], init, r.Left, n1) + fn := chanfn("chanrecv2", 2, r.Left().Type()) + ok := n.List().Second() + call := mkcall1(fn, types.Types[types.TBOOL], init, r.Left(), n1) n = ir.Nod(ir.OAS, ok, call) n = typecheck(n, ctxStmt) // a,b = m[i] case ir.OAS2MAPR: - init.AppendNodes(&n.Ninit) + init.AppendNodes(n.PtrInit()) - r := n.Right - walkexprlistsafe(n.List.Slice(), init) - r.Left = walkexpr(r.Left, init) - r.Right = walkexpr(r.Right, init) - t := r.Left.Type + r := n.Right() + walkexprlistsafe(n.List().Slice(), init) + r.SetLeft(walkexpr(r.Left(), init)) + r.SetRight(walkexpr(r.Right(), init)) + t := r.Left().Type() fast := mapfast(t) var key *ir.Node if fast != mapslow { // fast versions take key by value - key = r.Right + key = r.Right() } else { // standard version takes key by reference // order.expr made sure key is addressable. - key = ir.Nod(ir.OADDR, r.Right, nil) + key = ir.Nod(ir.OADDR, r.Right(), nil) } // from: @@ -738,32 +738,32 @@ opswitch: // to: // var,b = mapaccess2*(t, m, i) // a = *var - a := n.List.First() + a := n.List().First() if w := t.Elem().Width; w <= zeroValSize { fn := mapfn(mapaccess2[fast], t) - r = mkcall1(fn, fn.Type.Results(), init, typename(t), r.Left, key) + r = mkcall1(fn, fn.Type().Results(), init, typename(t), r.Left(), key) } else { fn := mapfn("mapaccess2_fat", t) z := zeroaddr(w) - r = mkcall1(fn, fn.Type.Results(), init, typename(t), r.Left, key, z) + r = mkcall1(fn, fn.Type().Results(), init, typename(t), r.Left(), key, z) } // mapaccess2* returns a typed bool, but due to spec changes, // the boolean result of i.(T) is now untyped so we make it the // same type as the variable on the lhs. - if ok := n.List.Second(); !ir.IsBlank(ok) && ok.Type.IsBoolean() { - r.Type.Field(1).Type = ok.Type + if ok := n.List().Second(); !ir.IsBlank(ok) && ok.Type().IsBoolean() { + r.Type().Field(1).Type = ok.Type() } - n.Right = r - n.Op = ir.OAS2FUNC + n.SetRight(r) + n.SetOp(ir.OAS2FUNC) // don't generate a = *var if a is _ if !ir.IsBlank(a) { var_ := temp(types.NewPtr(t.Elem())) var_.SetTypecheck(1) var_.MarkNonNil() // mapaccess always returns a non-nil pointer - n.List.SetFirst(var_) + n.List().SetFirst(var_) n = walkexpr(n, init) init.Append(n) n = ir.Nod(ir.OAS, a, ir.Nod(ir.ODEREF, var_, nil)) @@ -773,13 +773,13 @@ opswitch: n = walkexpr(n, init) case ir.ODELETE: - init.AppendNodes(&n.Ninit) - map_ := n.List.First() - key := n.List.Second() + init.AppendNodes(n.PtrInit()) + map_ := n.List().First() + key := n.List().Second() map_ = walkexpr(map_, init) key = walkexpr(key, init) - t := map_.Type + t := map_.Type() fast := mapfast(t) if fast == mapslow { // order.stmt made sure key is addressable. @@ -788,17 +788,17 @@ opswitch: n = mkcall1(mapfndel(mapdelete[fast], t), nil, init, typename(t), map_, key) case ir.OAS2DOTTYPE: - walkexprlistsafe(n.List.Slice(), init) - n.Right = walkexpr(n.Right, init) + walkexprlistsafe(n.List().Slice(), init) + n.SetRight(walkexpr(n.Right(), init)) case ir.OCONVIFACE: - n.Left = walkexpr(n.Left, init) + n.SetLeft(walkexpr(n.Left(), init)) - fromType := n.Left.Type - toType := n.Type + fromType := n.Left().Type() + toType := n.Type() - if !fromType.IsInterface() && !ir.IsBlank(Curfn.Func.Nname) { // skip unnamed functions (func _()) - markTypeUsedInInterface(fromType, Curfn.Func.LSym) + if !fromType.IsInterface() && !ir.IsBlank(Curfn.Func().Nname) { // skip unnamed functions (func _()) + markTypeUsedInInterface(fromType, Curfn.Func().LSym) } // typeword generates the type word of the interface value. @@ -811,8 +811,8 @@ opswitch: // Optimize convT2E or convT2I as a two-word copy when T is pointer-shaped. if isdirectiface(fromType) { - l := ir.Nod(ir.OEFACE, typeword(), n.Left) - l.Type = toType + l := ir.Nod(ir.OEFACE, typeword(), n.Left()) + l.SetType(toType) l.SetTypecheck(n.Typecheck()) n = l break @@ -823,10 +823,10 @@ opswitch: staticuint64s.SetClass(ir.PEXTERN) // The actual type is [256]uint64, but we use [256*8]uint8 so we can address // individual bytes. - staticuint64s.Type = types.NewArray(types.Types[types.TUINT8], 256*8) + staticuint64s.SetType(types.NewArray(types.Types[types.TUINT8], 256*8)) zerobase = NewName(Runtimepkg.Lookup("zerobase")) zerobase.SetClass(ir.PEXTERN) - zerobase.Type = types.Types[types.TUINTPTR] + zerobase.SetType(types.Types[types.TUINTPTR]) } // Optimize convT2{E,I} for many cases in which T is not pointer-shaped, @@ -836,33 +836,33 @@ opswitch: switch { case fromType.Size() == 0: // n.Left is zero-sized. Use zerobase. - cheapexpr(n.Left, init) // Evaluate n.Left for side-effects. See issue 19246. + cheapexpr(n.Left(), init) // Evaluate n.Left for side-effects. See issue 19246. value = zerobase case fromType.IsBoolean() || (fromType.Size() == 1 && fromType.IsInteger()): // n.Left is a bool/byte. Use staticuint64s[n.Left * 8] on little-endian // and staticuint64s[n.Left * 8 + 7] on big-endian. - n.Left = cheapexpr(n.Left, init) + n.SetLeft(cheapexpr(n.Left(), init)) // byteindex widens n.Left so that the multiplication doesn't overflow. - index := ir.Nod(ir.OLSH, byteindex(n.Left), nodintconst(3)) + index := ir.Nod(ir.OLSH, byteindex(n.Left()), nodintconst(3)) if thearch.LinkArch.ByteOrder == binary.BigEndian { index = ir.Nod(ir.OADD, index, nodintconst(7)) } value = ir.Nod(ir.OINDEX, staticuint64s, index) value.SetBounded(true) - case n.Left.Class() == ir.PEXTERN && n.Left.Name != nil && n.Left.Name.Readonly(): + case n.Left().Class() == ir.PEXTERN && n.Left().Name() != nil && n.Left().Name().Readonly(): // n.Left is a readonly global; use it directly. - value = n.Left - case !fromType.IsInterface() && n.Esc == EscNone && fromType.Width <= 1024: + value = n.Left() + case !fromType.IsInterface() && n.Esc() == EscNone && fromType.Width <= 1024: // n.Left does not escape. Use a stack temporary initialized to n.Left. value = temp(fromType) - init.Append(typecheck(ir.Nod(ir.OAS, value, n.Left), ctxStmt)) + init.Append(typecheck(ir.Nod(ir.OAS, value, n.Left()), ctxStmt)) } if value != nil { // Value is identical to n.Left. // Construct the interface directly: {type/itab, &value}. l := ir.Nod(ir.OEFACE, typeword(), typecheck(ir.Nod(ir.OADDR, value, nil), ctxExpr)) - l.Type = toType + l.SetType(toType) l.SetTypecheck(n.Typecheck()) n = l break @@ -877,7 +877,7 @@ opswitch: if toType.IsEmptyInterface() && fromType.IsInterface() && !fromType.IsEmptyInterface() { // Evaluate the input interface. c := temp(fromType) - init.Append(ir.Nod(ir.OAS, c, n.Left)) + init.Append(ir.Nod(ir.OAS, c, n.Left())) // Get the itab out of the interface. tmp := temp(types.NewPtr(types.Types[types.TUINT8])) @@ -885,12 +885,12 @@ opswitch: // Get the type out of the itab. nif := ir.Nod(ir.OIF, typecheck(ir.Nod(ir.ONE, tmp, nodnil()), ctxExpr), nil) - nif.Nbody.Set1(ir.Nod(ir.OAS, tmp, itabType(tmp))) + nif.PtrBody().Set1(ir.Nod(ir.OAS, tmp, itabType(tmp))) init.Append(nif) // Build the result. - e := ir.Nod(ir.OEFACE, tmp, ifaceData(n.Pos, c, types.NewPtr(types.Types[types.TUINT8]))) - e.Type = toType // assign type manually, typecheck doesn't understand OEFACE. + e := ir.Nod(ir.OEFACE, tmp, ifaceData(n.Pos(), c, types.NewPtr(types.Types[types.TUINT8]))) + e.SetType(toType) // assign type manually, typecheck doesn't understand OEFACE. e.SetTypecheck(1) n = e break @@ -905,14 +905,14 @@ opswitch: fn := syslook(fnname) dowidth(fromType) fn = substArgTypes(fn, fromType) - dowidth(fn.Type) + dowidth(fn.Type()) call := ir.Nod(ir.OCALL, fn, nil) - call.List.Set1(n.Left) + call.PtrList().Set1(n.Left()) call = typecheck(call, ctxExpr) call = walkexpr(call, init) call = safeexpr(call, init) e := ir.Nod(ir.OEFACE, typeword(), call) - e.Type = toType + e.SetType(toType) e.SetTypecheck(1) n = e break @@ -927,7 +927,7 @@ opswitch: tab = typeword() } - v := n.Left + v := n.Left() if needsaddr { // Types of large or unknown size are passed by reference. // Orderexpr arranged for n.Left to be a temporary for all @@ -936,7 +936,7 @@ opswitch: // with non-interface cases, is not visible to order.stmt, so we // have to fall back on allocating a temp here. if !islvalue(v) { - v = copyexpr(v, v.Type, init) + v = copyexpr(v, v.Type(), init) } v = ir.Nod(ir.OADDR, v, nil) } @@ -944,41 +944,41 @@ opswitch: dowidth(fromType) fn := syslook(fnname) fn = substArgTypes(fn, fromType, toType) - dowidth(fn.Type) + dowidth(fn.Type()) n = ir.Nod(ir.OCALL, fn, nil) - n.List.Set2(tab, v) + n.PtrList().Set2(tab, v) n = typecheck(n, ctxExpr) n = walkexpr(n, init) case ir.OCONV, ir.OCONVNOP: - n.Left = walkexpr(n.Left, init) - if n.Op == ir.OCONVNOP && checkPtr(Curfn, 1) { - if n.Type.IsPtr() && n.Left.Type.IsUnsafePtr() { // unsafe.Pointer to *T + n.SetLeft(walkexpr(n.Left(), init)) + if n.Op() == ir.OCONVNOP && checkPtr(Curfn, 1) { + if n.Type().IsPtr() && n.Left().Type().IsUnsafePtr() { // unsafe.Pointer to *T n = walkCheckPtrAlignment(n, init, nil) break } - if n.Type.IsUnsafePtr() && n.Left.Type.IsUintptr() { // uintptr to unsafe.Pointer + if n.Type().IsUnsafePtr() && n.Left().Type().IsUintptr() { // uintptr to unsafe.Pointer n = walkCheckPtrArithmetic(n, init) break } } - param, result := rtconvfn(n.Left.Type, n.Type) + param, result := rtconvfn(n.Left().Type(), n.Type()) if param == types.Txxx { break } fn := ir.BasicTypeNames[param] + "to" + ir.BasicTypeNames[result] - n = conv(mkcall(fn, types.Types[result], init, conv(n.Left, types.Types[param])), n.Type) + n = conv(mkcall(fn, types.Types[result], init, conv(n.Left(), types.Types[param])), n.Type()) case ir.ODIV, ir.OMOD: - n.Left = walkexpr(n.Left, init) - n.Right = walkexpr(n.Right, init) + n.SetLeft(walkexpr(n.Left(), init)) + n.SetRight(walkexpr(n.Right(), init)) // rewrite complex div into function call. - et := n.Left.Type.Etype + et := n.Left().Type().Etype - if isComplex[et] && n.Op == ir.ODIV { - t := n.Type - n = mkcall("complex128div", types.Types[types.TCOMPLEX128], init, conv(n.Left, types.Types[types.TCOMPLEX128]), conv(n.Right, types.Types[types.TCOMPLEX128])) + if isComplex[et] && n.Op() == ir.ODIV { + t := n.Type() + n = mkcall("complex128div", types.Types[types.TCOMPLEX128], init, conv(n.Left(), types.Types[types.TCOMPLEX128]), conv(n.Right(), types.Types[types.TCOMPLEX128])) n = conv(n, t) break } @@ -992,12 +992,12 @@ opswitch: // TODO: Remove this code once we can introduce // runtime calls late in SSA processing. if Widthreg < 8 && (et == types.TINT64 || et == types.TUINT64) { - if n.Right.Op == ir.OLITERAL { + if n.Right().Op() == ir.OLITERAL { // Leave div/mod by constant powers of 2 or small 16-bit constants. // The SSA backend will handle those. switch et { case types.TINT64: - c := n.Right.Int64Val() + c := n.Right().Int64Val() if c < 0 { c = -c } @@ -1005,7 +1005,7 @@ opswitch: break opswitch } case types.TUINT64: - c := n.Right.Uint64Val() + c := n.Right().Uint64Val() if c < 1<<16 { break opswitch } @@ -1020,63 +1020,63 @@ opswitch: } else { fn = "uint64" } - if n.Op == ir.ODIV { + if n.Op() == ir.ODIV { fn += "div" } else { fn += "mod" } - n = mkcall(fn, n.Type, init, conv(n.Left, types.Types[et]), conv(n.Right, types.Types[et])) + n = mkcall(fn, n.Type(), init, conv(n.Left(), types.Types[et]), conv(n.Right(), types.Types[et])) } case ir.OINDEX: - n.Left = walkexpr(n.Left, init) + n.SetLeft(walkexpr(n.Left(), init)) // save the original node for bounds checking elision. // If it was a ODIV/OMOD walk might rewrite it. - r := n.Right + r := n.Right() - n.Right = walkexpr(n.Right, init) + n.SetRight(walkexpr(n.Right(), init)) // if range of type cannot exceed static array bound, // disable bounds check. if n.Bounded() { break } - t := n.Left.Type + t := n.Left().Type() if t != nil && t.IsPtr() { t = t.Elem() } if t.IsArray() { n.SetBounded(bounded(r, t.NumElem())) - if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Right, constant.Int) { + if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Right(), constant.Int) { base.Warn("index bounds check elided") } - if smallintconst(n.Right) && !n.Bounded() { + if smallintconst(n.Right()) && !n.Bounded() { base.Errorf("index out of bounds") } - } else if ir.IsConst(n.Left, constant.String) { - n.SetBounded(bounded(r, int64(len(n.Left.StringVal())))) - if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Right, constant.Int) { + } else if ir.IsConst(n.Left(), constant.String) { + n.SetBounded(bounded(r, int64(len(n.Left().StringVal())))) + if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Right(), constant.Int) { base.Warn("index bounds check elided") } - if smallintconst(n.Right) && !n.Bounded() { + if smallintconst(n.Right()) && !n.Bounded() { base.Errorf("index out of bounds") } } - if ir.IsConst(n.Right, constant.Int) { - if v := n.Right.Val(); constant.Sign(v) < 0 || doesoverflow(v, types.Types[types.TINT]) { + if ir.IsConst(n.Right(), constant.Int) { + if v := n.Right().Val(); constant.Sign(v) < 0 || doesoverflow(v, types.Types[types.TINT]) { base.Errorf("index out of bounds") } } case ir.OINDEXMAP: // Replace m[k] with *map{access1,assign}(maptype, m, &k) - n.Left = walkexpr(n.Left, init) - n.Right = walkexpr(n.Right, init) - map_ := n.Left - key := n.Right - t := map_.Type + n.SetLeft(walkexpr(n.Left(), init)) + n.SetRight(walkexpr(n.Right(), init)) + map_ := n.Left() + key := n.Right() + t := map_.Type() if n.IndexMapLValue() { // This m[k] expression is on the left-hand side of an assignment. fast := mapfast(t) @@ -1102,26 +1102,26 @@ opswitch: n = mkcall1(mapfn("mapaccess1_fat", t), types.NewPtr(t.Elem()), init, typename(t), map_, key, z) } } - n.Type = types.NewPtr(t.Elem()) + n.SetType(types.NewPtr(t.Elem())) n.MarkNonNil() // mapaccess1* and mapassign always return non-nil pointers. n = ir.Nod(ir.ODEREF, n, nil) - n.Type = t.Elem() + n.SetType(t.Elem()) n.SetTypecheck(1) case ir.ORECV: base.Fatalf("walkexpr ORECV") // should see inside OAS only case ir.OSLICEHEADER: - n.Left = walkexpr(n.Left, init) - n.List.SetFirst(walkexpr(n.List.First(), init)) - n.List.SetSecond(walkexpr(n.List.Second(), init)) + n.SetLeft(walkexpr(n.Left(), init)) + n.List().SetFirst(walkexpr(n.List().First(), init)) + n.List().SetSecond(walkexpr(n.List().Second(), init)) case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR: - checkSlice := checkPtr(Curfn, 1) && n.Op == ir.OSLICE3ARR && n.Left.Op == ir.OCONVNOP && n.Left.Left.Type.IsUnsafePtr() + checkSlice := checkPtr(Curfn, 1) && n.Op() == ir.OSLICE3ARR && n.Left().Op() == ir.OCONVNOP && n.Left().Left().Type().IsUnsafePtr() if checkSlice { - n.Left.Left = walkexpr(n.Left.Left, init) + n.Left().SetLeft(walkexpr(n.Left().Left(), init)) } else { - n.Left = walkexpr(n.Left, init) + n.SetLeft(walkexpr(n.Left(), init)) } low, high, max := n.SliceBounds() low = walkexpr(low, init) @@ -1133,15 +1133,15 @@ opswitch: max = walkexpr(max, init) n.SetSliceBounds(low, high, max) if checkSlice { - n.Left = walkCheckPtrAlignment(n.Left, init, max) + n.SetLeft(walkCheckPtrAlignment(n.Left(), init, max)) } - if n.Op.IsSlice3() { - if max != nil && max.Op == ir.OCAP && samesafeexpr(n.Left, max.Left) { + if n.Op().IsSlice3() { + if max != nil && max.Op() == ir.OCAP && samesafeexpr(n.Left(), max.Left()) { // Reduce x[i:j:cap(x)] to x[i:j]. - if n.Op == ir.OSLICE3 { - n.Op = ir.OSLICE + if n.Op() == ir.OSLICE3 { + n.SetOp(ir.OSLICE) } else { - n.Op = ir.OSLICEARR + n.SetOp(ir.OSLICEARR) } n = reduceSlice(n) } @@ -1150,22 +1150,22 @@ opswitch: } case ir.ONEW: - if n.Type.Elem().NotInHeap() { - base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", n.Type.Elem()) + if n.Type().Elem().NotInHeap() { + base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", n.Type().Elem()) } - if n.Esc == EscNone { - if n.Type.Elem().Width >= maxImplicitStackVarSize { + if n.Esc() == EscNone { + if n.Type().Elem().Width >= maxImplicitStackVarSize { base.Fatalf("large ONEW with EscNone: %v", n) } - r := temp(n.Type.Elem()) + r := temp(n.Type().Elem()) r = ir.Nod(ir.OAS, r, nil) // zero temp r = typecheck(r, ctxStmt) init.Append(r) - r = ir.Nod(ir.OADDR, r.Left, nil) + r = ir.Nod(ir.OADDR, r.Left(), nil) r = typecheck(r, ctxExpr) n = r } else { - n = callnew(n.Type.Elem()) + n = callnew(n.Type().Elem()) } case ir.OADDSTR: @@ -1182,34 +1182,34 @@ opswitch: case ir.OCLOSE: fn := syslook("closechan") - fn = substArgTypes(fn, n.Left.Type) - n = mkcall1(fn, nil, init, n.Left) + fn = substArgTypes(fn, n.Left().Type()) + n = mkcall1(fn, nil, init, n.Left()) case ir.OMAKECHAN: // When size fits into int, use makechan instead of // makechan64, which is faster and shorter on 32 bit platforms. - size := n.Left + size := n.Left() fnname := "makechan64" argtype := types.Types[types.TINT64] // Type checking guarantees that TIDEAL size is positive and fits in an int. // The case of size overflow when converting TUINT or TUINTPTR to TINT // will be handled by the negative range checks in makechan during runtime. - if size.Type.IsKind(types.TIDEAL) || size.Type.Size() <= types.Types[types.TUINT].Size() { + if size.Type().IsKind(types.TIDEAL) || size.Type().Size() <= types.Types[types.TUINT].Size() { fnname = "makechan" argtype = types.Types[types.TINT] } - n = mkcall1(chanfn(fnname, 1, n.Type), n.Type, init, typename(n.Type), conv(size, argtype)) + n = mkcall1(chanfn(fnname, 1, n.Type()), n.Type(), init, typename(n.Type()), conv(size, argtype)) case ir.OMAKEMAP: - t := n.Type + t := n.Type() hmapType := hmap(t) - hint := n.Left + hint := n.Left() // var h *hmap var h *ir.Node - if n.Esc == EscNone { + if n.Esc() == EscNone { // Allocate hmap on stack. // var hv hmap @@ -1243,7 +1243,7 @@ opswitch: // var bv bmap bv := temp(bmap(t)) zero = ir.Nod(ir.OAS, bv, nil) - nif.Nbody.Append(zero) + nif.PtrBody().Append(zero) // b = &bv b := ir.Nod(ir.OADDR, bv, nil) @@ -1251,7 +1251,7 @@ opswitch: // h.buckets = b bsym := hmapType.Field(5).Sym // hmap.buckets see reflect.go:hmap na := ir.Nod(ir.OAS, nodSym(ir.ODOT, h, bsym), b) - nif.Nbody.Append(na) + nif.PtrBody().Append(na) nif = typecheck(nif, ctxStmt) nif = walkstmt(nif) @@ -1267,7 +1267,7 @@ opswitch: // For hint <= BUCKETSIZE overLoadFactor(hint, 0) is false // and no buckets will be allocated by makemap. Therefore, // no buckets need to be allocated in this code path. - if n.Esc == EscNone { + if n.Esc() == EscNone { // Only need to initialize h.hash0 since // hmap h has been allocated on the stack already. // h.hash0 = fastrand() @@ -1283,10 +1283,10 @@ opswitch: // hmap on the heap and initialize hmap's hash0 field. fn := syslook("makemap_small") fn = substArgTypes(fn, t.Key(), t.Elem()) - n = mkcall1(fn, n.Type, init) + n = mkcall1(fn, n.Type(), init) } } else { - if n.Esc != EscNone { + if n.Esc() != EscNone { h = nodnil() } // Map initialization with a variable or large hint is @@ -1303,28 +1303,28 @@ opswitch: // See checkmake call in TMAP case of OMAKE case in OpSwitch in typecheck1 function. // The case of hint overflow when converting TUINT or TUINTPTR to TINT // will be handled by the negative range checks in makemap during runtime. - if hint.Type.IsKind(types.TIDEAL) || hint.Type.Size() <= types.Types[types.TUINT].Size() { + if hint.Type().IsKind(types.TIDEAL) || hint.Type().Size() <= types.Types[types.TUINT].Size() { fnname = "makemap" argtype = types.Types[types.TINT] } fn := syslook(fnname) fn = substArgTypes(fn, hmapType, t.Key(), t.Elem()) - n = mkcall1(fn, n.Type, init, typename(n.Type), conv(hint, argtype), h) + n = mkcall1(fn, n.Type(), init, typename(n.Type()), conv(hint, argtype), h) } case ir.OMAKESLICE: - l := n.Left - r := n.Right + l := n.Left() + r := n.Right() if r == nil { r = safeexpr(l, init) l = r } - t := n.Type + t := n.Type() if t.Elem().NotInHeap() { base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem()) } - if n.Esc == EscNone { + if n.Esc() == EscNone { if why := heapAllocReason(n); why != "" { base.Fatalf("%v has EscNone, but %v", n, why) } @@ -1344,8 +1344,8 @@ opswitch: // } nif := ir.Nod(ir.OIF, ir.Nod(ir.OGT, conv(l, types.Types[types.TUINT64]), nodintconst(i)), nil) niflen := ir.Nod(ir.OIF, ir.Nod(ir.OLT, l, nodintconst(0)), nil) - niflen.Nbody.Set1(mkcall("panicmakeslicelen", nil, init)) - nif.Nbody.Append(niflen, mkcall("panicmakeslicecap", nil, init)) + niflen.PtrBody().Set1(mkcall("panicmakeslicelen", nil, init)) + nif.PtrBody().Append(niflen, mkcall("panicmakeslicecap", nil, init)) nif = typecheck(nif, ctxStmt) init.Append(nif) @@ -1356,7 +1356,7 @@ opswitch: init.Append(a) r := ir.Nod(ir.OSLICE, var_, nil) // arr[:l] r.SetSliceBounds(nil, l, nil) - r = conv(r, n.Type) // in case n.Type is named. + r = conv(r, n.Type()) // in case n.Type is named. r = typecheck(r, ctxExpr) r = walkexpr(r, init) n = r @@ -1373,19 +1373,19 @@ opswitch: // Type checking guarantees that TIDEAL len/cap are positive and fit in an int. // The case of len or cap overflow when converting TUINT or TUINTPTR to TINT // will be handled by the negative range checks in makeslice during runtime. - if (len.Type.IsKind(types.TIDEAL) || len.Type.Size() <= types.Types[types.TUINT].Size()) && - (cap.Type.IsKind(types.TIDEAL) || cap.Type.Size() <= types.Types[types.TUINT].Size()) { + if (len.Type().IsKind(types.TIDEAL) || len.Type().Size() <= types.Types[types.TUINT].Size()) && + (cap.Type().IsKind(types.TIDEAL) || cap.Type().Size() <= types.Types[types.TUINT].Size()) { fnname = "makeslice" argtype = types.Types[types.TINT] } m := ir.Nod(ir.OSLICEHEADER, nil, nil) - m.Type = t + m.SetType(t) fn := syslook(fnname) - m.Left = mkcall1(fn, types.Types[types.TUNSAFEPTR], init, typename(t.Elem()), conv(len, argtype), conv(cap, argtype)) - m.Left.MarkNonNil() - m.List.Set2(conv(len, types.Types[types.TINT]), conv(cap, types.Types[types.TINT])) + m.SetLeft(mkcall1(fn, types.Types[types.TUNSAFEPTR], init, typename(t.Elem()), conv(len, argtype), conv(cap, argtype))) + m.Left().MarkNonNil() + m.PtrList().Set2(conv(len, types.Types[types.TINT]), conv(cap, types.Types[types.TINT])) m = typecheck(m, ctxExpr) m = walkexpr(m, init) @@ -1393,18 +1393,18 @@ opswitch: } case ir.OMAKESLICECOPY: - if n.Esc == EscNone { + if n.Esc() == EscNone { base.Fatalf("OMAKESLICECOPY with EscNone: %v", n) } - t := n.Type + t := n.Type() if t.Elem().NotInHeap() { base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem()) } - length := conv(n.Left, types.Types[types.TINT]) - copylen := ir.Nod(ir.OLEN, n.Right, nil) - copyptr := ir.Nod(ir.OSPTR, n.Right, nil) + length := conv(n.Left(), types.Types[types.TINT]) + copylen := ir.Nod(ir.OLEN, n.Right(), nil) + copyptr := ir.Nod(ir.OSPTR, n.Right(), nil) if !t.Elem().HasPointers() && n.Bounded() { // When len(to)==len(from) and elements have no pointers: @@ -1418,10 +1418,10 @@ opswitch: // instantiate mallocgc(size uintptr, typ *byte, needszero bool) unsafe.Pointer fn := syslook("mallocgc") sh := ir.Nod(ir.OSLICEHEADER, nil, nil) - sh.Left = mkcall1(fn, types.Types[types.TUNSAFEPTR], init, size, nodnil(), nodbool(false)) - sh.Left.MarkNonNil() - sh.List.Set2(length, length) - sh.Type = t + sh.SetLeft(mkcall1(fn, types.Types[types.TUNSAFEPTR], init, size, nodnil(), nodbool(false))) + sh.Left().MarkNonNil() + sh.PtrList().Set2(length, length) + sh.SetType(t) s := temp(t) r := typecheck(ir.Nod(ir.OAS, s, sh), ctxStmt) @@ -1441,61 +1441,61 @@ opswitch: // instantiate makeslicecopy(typ *byte, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer fn := syslook("makeslicecopy") s := ir.Nod(ir.OSLICEHEADER, nil, nil) - s.Left = mkcall1(fn, types.Types[types.TUNSAFEPTR], init, typename(t.Elem()), length, copylen, conv(copyptr, types.Types[types.TUNSAFEPTR])) - s.Left.MarkNonNil() - s.List.Set2(length, length) - s.Type = t + s.SetLeft(mkcall1(fn, types.Types[types.TUNSAFEPTR], init, typename(t.Elem()), length, copylen, conv(copyptr, types.Types[types.TUNSAFEPTR]))) + s.Left().MarkNonNil() + s.PtrList().Set2(length, length) + s.SetType(t) n = typecheck(s, ctxExpr) n = walkexpr(n, init) } case ir.ORUNESTR: a := nodnil() - if n.Esc == EscNone { + if n.Esc() == EscNone { t := types.NewArray(types.Types[types.TUINT8], 4) a = ir.Nod(ir.OADDR, temp(t), nil) } // intstring(*[4]byte, rune) - n = mkcall("intstring", n.Type, init, a, conv(n.Left, types.Types[types.TINT64])) + n = mkcall("intstring", n.Type(), init, a, conv(n.Left(), types.Types[types.TINT64])) case ir.OBYTES2STR, ir.ORUNES2STR: a := nodnil() - if n.Esc == EscNone { + if n.Esc() == EscNone { // Create temporary buffer for string on stack. t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize) a = ir.Nod(ir.OADDR, temp(t), nil) } - if n.Op == ir.ORUNES2STR { + if n.Op() == ir.ORUNES2STR { // slicerunetostring(*[32]byte, []rune) string - n = mkcall("slicerunetostring", n.Type, init, a, n.Left) + n = mkcall("slicerunetostring", n.Type(), init, a, n.Left()) } else { // slicebytetostring(*[32]byte, ptr *byte, n int) string - n.Left = cheapexpr(n.Left, init) - ptr, len := backingArrayPtrLen(n.Left) - n = mkcall("slicebytetostring", n.Type, init, a, ptr, len) + n.SetLeft(cheapexpr(n.Left(), init)) + ptr, len := backingArrayPtrLen(n.Left()) + n = mkcall("slicebytetostring", n.Type(), init, a, ptr, len) } case ir.OBYTES2STRTMP: - n.Left = walkexpr(n.Left, init) + n.SetLeft(walkexpr(n.Left(), init)) if !instrumenting { // Let the backend handle OBYTES2STRTMP directly // to avoid a function call to slicebytetostringtmp. break } // slicebytetostringtmp(ptr *byte, n int) string - n.Left = cheapexpr(n.Left, init) - ptr, len := backingArrayPtrLen(n.Left) - n = mkcall("slicebytetostringtmp", n.Type, init, ptr, len) + n.SetLeft(cheapexpr(n.Left(), init)) + ptr, len := backingArrayPtrLen(n.Left()) + n = mkcall("slicebytetostringtmp", n.Type(), init, ptr, len) case ir.OSTR2BYTES: - s := n.Left + s := n.Left() if ir.IsConst(s, constant.String) { sc := s.StringVal() // Allocate a [n]byte of the right size. t := types.NewArray(types.Types[types.TUINT8], int64(len(sc))) var a *ir.Node - if n.Esc == EscNone && len(sc) <= int(maxImplicitStackVarSize) { + if n.Esc() == EscNone && len(sc) <= int(maxImplicitStackVarSize) { a = ir.Nod(ir.OADDR, temp(t), nil) } else { a = callnew(t) @@ -1514,20 +1514,20 @@ opswitch: } // Slice the [n]byte to a []byte. - n.Op = ir.OSLICEARR - n.Left = p + n.SetOp(ir.OSLICEARR) + n.SetLeft(p) n = walkexpr(n, init) break } a := nodnil() - if n.Esc == EscNone { + if n.Esc() == EscNone { // Create temporary buffer for slice on stack. t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize) a = ir.Nod(ir.OADDR, temp(t), nil) } // stringtoslicebyte(*32[byte], string) []byte - n = mkcall("stringtoslicebyte", n.Type, init, a, conv(s, types.Types[types.TSTRING])) + n = mkcall("stringtoslicebyte", n.Type(), init, a, conv(s, types.Types[types.TSTRING])) case ir.OSTR2BYTESTMP: // []byte(string) conversion that creates a slice @@ -1537,38 +1537,38 @@ opswitch: // that know that the slice won't be mutated. // The only such case today is: // for i, c := range []byte(string) - n.Left = walkexpr(n.Left, init) + n.SetLeft(walkexpr(n.Left(), init)) case ir.OSTR2RUNES: a := nodnil() - if n.Esc == EscNone { + if n.Esc() == EscNone { // Create temporary buffer for slice on stack. t := types.NewArray(types.Types[types.TINT32], tmpstringbufsize) a = ir.Nod(ir.OADDR, temp(t), nil) } // stringtoslicerune(*[32]rune, string) []rune - n = mkcall("stringtoslicerune", n.Type, init, a, conv(n.Left, types.Types[types.TSTRING])) + n = mkcall("stringtoslicerune", n.Type(), init, a, conv(n.Left(), types.Types[types.TSTRING])) case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT, ir.OSTRUCTLIT, ir.OPTRLIT: - if isStaticCompositeLiteral(n) && !canSSAType(n.Type) { + if isStaticCompositeLiteral(n) && !canSSAType(n.Type()) { // n can be directly represented in the read-only data section. // Make direct reference to the static data. See issue 12841. - vstat := readonlystaticname(n.Type) + vstat := readonlystaticname(n.Type()) fixedlit(inInitFunction, initKindStatic, n, vstat, init) n = vstat n = typecheck(n, ctxExpr) break } - var_ := temp(n.Type) + var_ := temp(n.Type()) anylit(n, var_, init) n = var_ case ir.OSEND: - n1 := n.Right - n1 = assignconv(n1, n.Left.Type.Elem(), "chan send") + n1 := n.Right() + n1 = assignconv(n1, n.Left().Type().Elem(), "chan send") n1 = walkexpr(n1, init) n1 = ir.Nod(ir.OADDR, n1, nil) - n = mkcall1(chanfn("chansend1", 2, n.Left.Type), nil, init, n.Left, n1) + n = mkcall1(chanfn("chansend1", 2, n.Left().Type()), nil, init, n.Left(), n1) case ir.OCLOSURE: n = walkclosure(n, init) @@ -1582,17 +1582,17 @@ opswitch: // constants until walk. For example, if n is y%1 == 0, the // walk of y%1 may have replaced it by 0. // Check whether n with its updated args is itself now a constant. - t := n.Type + t := n.Type() n = evalConst(n) - if n.Type != t { - base.Fatalf("evconst changed Type: %v had type %v, now %v", n, t, n.Type) + if n.Type() != t { + base.Fatalf("evconst changed Type: %v had type %v, now %v", n, t, n.Type()) } - if n.Op == ir.OLITERAL { + if n.Op() == ir.OLITERAL { n = typecheck(n, ctxExpr) // Emit string symbol now to avoid emitting // any concurrently during the backend. if v := n.Val(); v.Kind() == constant.String { - _ = stringsym(n.Pos, constant.StringVal(v)) + _ = stringsym(n.Pos(), constant.StringVal(v)) } } @@ -1620,13 +1620,13 @@ func markTypeUsedInInterface(t *types.Type, from *obj.LSym) { // markUsedIfaceMethod marks that an interface method is used in the current // function. n is OCALLINTER node. func markUsedIfaceMethod(n *ir.Node) { - ityp := n.Left.Left.Type + ityp := n.Left().Left().Type() tsym := typenamesym(ityp).Linksym() - r := obj.Addrel(Curfn.Func.LSym) + r := obj.Addrel(Curfn.Func().LSym) r.Sym = tsym // n.Left.Xoffset is the method index * Widthptr (the offset of code pointer // in itab). - midx := n.Left.Xoffset / int64(Widthptr) + midx := n.Left().Offset() / int64(Widthptr) r.Add = ifaceMethodOffset(ityp, midx) r.Type = objabi.R_USEIFACEMETHOD } @@ -1680,17 +1680,17 @@ func rtconvfn(src, dst *types.Type) (param, result types.EType) { // TODO(josharian): combine this with its caller and simplify func reduceSlice(n *ir.Node) *ir.Node { low, high, max := n.SliceBounds() - if high != nil && high.Op == ir.OLEN && samesafeexpr(n.Left, high.Left) { + if high != nil && high.Op() == ir.OLEN && samesafeexpr(n.Left(), high.Left()) { // Reduce x[i:len(x)] to x[i:]. high = nil } n.SetSliceBounds(low, high, max) - if (n.Op == ir.OSLICE || n.Op == ir.OSLICESTR) && low == nil && high == nil { + if (n.Op() == ir.OSLICE || n.Op() == ir.OSLICESTR) && low == nil && high == nil { // Reduce x[:] to x. if base.Debug.Slice > 0 { base.Warn("slice: omit slice operation") } - return n.Left + return n.Left() } return n } @@ -1700,7 +1700,7 @@ func ascompatee1(l *ir.Node, r *ir.Node, init *ir.Nodes) *ir.Node { // making it impossible for reorder3 to work. n := ir.Nod(ir.OAS, l, r) - if l.Op == ir.OINDEXMAP { + if l.Op() == ir.OINDEXMAP { return n } @@ -1745,10 +1745,10 @@ func ascompatee(op ir.Op, nl, nr []*ir.Node, init *ir.Nodes) []*ir.Node { // fncall reports whether assigning an rvalue of type rt to an lvalue l might involve a function call. func fncall(l *ir.Node, rt *types.Type) bool { - if l.HasCall() || l.Op == ir.OINDEXMAP { + if l.HasCall() || l.Op() == ir.OINDEXMAP { return true } - if types.Identical(l.Type, rt) { + if types.Identical(l.Type(), rt) { return false } // There might be a conversion required, which might involve a runtime call. @@ -1782,8 +1782,8 @@ func ascompatet(nl ir.Nodes, nr *types.Type) []*ir.Node { } res := ir.Nod(ir.ORESULT, nil, nil) - res.Xoffset = base.Ctxt.FixedFrameSize() + r.Offset - res.Type = r.Type + res.SetOffset(base.Ctxt.FixedFrameSize() + r.Offset) + res.SetType(r.Type) res.SetTypecheck(1) a := ir.Nod(ir.OAS, l, res) @@ -1804,15 +1804,15 @@ func mkdotargslice(typ *types.Type, args []*ir.Node) *ir.Node { var n *ir.Node if len(args) == 0 { n = nodnil() - n.Type = typ + n.SetType(typ) } else { n = ir.Nod(ir.OCOMPLIT, nil, typenod(typ)) - n.List.Append(args...) + n.PtrList().Append(args...) n.SetImplicit(true) } n = typecheck(n, ctxExpr) - if n.Type == nil { + if n.Type() == nil { base.Fatalf("mkdotargslice: typecheck failed") } return n @@ -1821,7 +1821,7 @@ func mkdotargslice(typ *types.Type, args []*ir.Node) *ir.Node { // fixVariadicCall rewrites calls to variadic functions to use an // explicit ... argument if one is not already present. func fixVariadicCall(call *ir.Node) { - fntype := call.Left.Type + fntype := call.Left().Type() if !fntype.IsVariadic() || call.IsDDD() { return } @@ -1829,33 +1829,33 @@ func fixVariadicCall(call *ir.Node) { vi := fntype.NumParams() - 1 vt := fntype.Params().Field(vi).Type - args := call.List.Slice() + args := call.List().Slice() extra := args[vi:] slice := mkdotargslice(vt, extra) for i := range extra { extra[i] = nil // allow GC } - call.List.Set(append(args[:vi], slice)) + call.PtrList().Set(append(args[:vi], slice)) call.SetIsDDD(true) } func walkCall(n *ir.Node, init *ir.Nodes) { - if n.Rlist.Len() != 0 { + if n.Rlist().Len() != 0 { return // already walked } - params := n.Left.Type.Params() - args := n.List.Slice() + params := n.Left().Type().Params() + args := n.List().Slice() - n.Left = walkexpr(n.Left, init) + n.SetLeft(walkexpr(n.Left(), init)) walkexprlist(args, init) // If this is a method call, add the receiver at the beginning of the args. - if n.Op == ir.OCALLMETH { + if n.Op() == ir.OCALLMETH { withRecv := make([]*ir.Node, len(args)+1) - withRecv[0] = n.Left.Left - n.Left.Left = nil + withRecv[0] = n.Left().Left() + n.Left().SetLeft(nil) copy(withRecv[1:], args) args = withRecv } @@ -1869,9 +1869,9 @@ func walkCall(n *ir.Node, init *ir.Nodes) { updateHasCall(arg) // Determine param type. var t *types.Type - if n.Op == ir.OCALLMETH { + if n.Op() == ir.OCALLMETH { if i == 0 { - t = n.Left.Type.Recv().Type + t = n.Left().Type().Recv().Type } else { t = params.Field(i - 1).Type } @@ -1889,18 +1889,18 @@ func walkCall(n *ir.Node, init *ir.Nodes) { } } - n.List.Set(tempAssigns) - n.Rlist.Set(args) + n.PtrList().Set(tempAssigns) + n.PtrRlist().Set(args) } // generate code for print func walkprint(nn *ir.Node, init *ir.Nodes) *ir.Node { // Hoist all the argument evaluation up before the lock. - walkexprlistcheap(nn.List.Slice(), init) + walkexprlistcheap(nn.List().Slice(), init) // For println, add " " between elements and "\n" at the end. - if nn.Op == ir.OPRINTN { - s := nn.List.Slice() + if nn.Op() == ir.OPRINTN { + s := nn.List().Slice() t := make([]*ir.Node, 0, len(s)*2) for i, n := range s { if i != 0 { @@ -1909,11 +1909,11 @@ func walkprint(nn *ir.Node, init *ir.Nodes) *ir.Node { t = append(t, n) } t = append(t, nodstr("\n")) - nn.List.Set(t) + nn.PtrList().Set(t) } // Collapse runs of constant strings. - s := nn.List.Slice() + s := nn.List().Slice() t := make([]*ir.Node, 0, len(s)) for i := 0; i < len(s); { var strs []string @@ -1929,12 +1929,12 @@ func walkprint(nn *ir.Node, init *ir.Nodes) *ir.Node { i++ } } - nn.List.Set(t) + nn.PtrList().Set(t) calls := []*ir.Node{mkcall("printlock", nil, init)} - for i, n := range nn.List.Slice() { - if n.Op == ir.OLITERAL { - if n.Type == types.UntypedRune { + for i, n := range nn.List().Slice() { + if n.Op() == ir.OLITERAL { + if n.Type() == types.UntypedRune { n = defaultlit(n, types.Runetype) } @@ -1947,42 +1947,42 @@ func walkprint(nn *ir.Node, init *ir.Nodes) *ir.Node { } } - if n.Op != ir.OLITERAL && n.Type != nil && n.Type.Etype == types.TIDEAL { + if n.Op() != ir.OLITERAL && n.Type() != nil && n.Type().Etype == types.TIDEAL { n = defaultlit(n, types.Types[types.TINT64]) } n = defaultlit(n, nil) - nn.List.SetIndex(i, n) - if n.Type == nil || n.Type.Etype == types.TFORW { + nn.List().SetIndex(i, n) + if n.Type() == nil || n.Type().Etype == types.TFORW { continue } var on *ir.Node - switch n.Type.Etype { + switch n.Type().Etype { case types.TINTER: - if n.Type.IsEmptyInterface() { + if n.Type().IsEmptyInterface() { on = syslook("printeface") } else { on = syslook("printiface") } - on = substArgTypes(on, n.Type) // any-1 + on = substArgTypes(on, n.Type()) // any-1 case types.TPTR: - if n.Type.Elem().NotInHeap() { + if n.Type().Elem().NotInHeap() { on = syslook("printuintptr") n = ir.Nod(ir.OCONV, n, nil) - n.Type = types.Types[types.TUNSAFEPTR] + n.SetType(types.Types[types.TUNSAFEPTR]) n = ir.Nod(ir.OCONV, n, nil) - n.Type = types.Types[types.TUINTPTR] + n.SetType(types.Types[types.TUINTPTR]) break } fallthrough case types.TCHAN, types.TMAP, types.TFUNC, types.TUNSAFEPTR: on = syslook("printpointer") - on = substArgTypes(on, n.Type) // any-1 + on = substArgTypes(on, n.Type()) // any-1 case types.TSLICE: on = syslook("printslice") - on = substArgTypes(on, n.Type) // any-1 + on = substArgTypes(on, n.Type()) // any-1 case types.TUINT, types.TUINT8, types.TUINT16, types.TUINT32, types.TUINT64, types.TUINTPTR: - if isRuntimePkg(n.Type.Sym.Pkg) && n.Type.Sym.Name == "hex" { + if isRuntimePkg(n.Type().Sym.Pkg) && n.Type().Sym.Name == "hex" { on = syslook("printhex") } else { on = syslook("printuint") @@ -2009,18 +2009,18 @@ func walkprint(nn *ir.Node, init *ir.Nodes) *ir.Node { on = syslook("printstring") } default: - badtype(ir.OPRINT, n.Type, nil) + badtype(ir.OPRINT, n.Type(), nil) continue } r := ir.Nod(ir.OCALL, on, nil) - if params := on.Type.Params().FieldSlice(); len(params) > 0 { + if params := on.Type().Params().FieldSlice(); len(params) > 0 { t := params[0].Type - if !types.Identical(t, n.Type) { + if !types.Identical(t, n.Type()) { n = ir.Nod(ir.OCONV, n, nil) - n.Type = t + n.SetType(t) } - r.List.Append(n) + r.PtrList().Append(n) } calls = append(calls, r) } @@ -2033,14 +2033,14 @@ func walkprint(nn *ir.Node, init *ir.Nodes) *ir.Node { r := ir.Nod(ir.OEMPTY, nil, nil) r = typecheck(r, ctxStmt) r = walkexpr(r, init) - r.Ninit.Set(calls) + r.PtrInit().Set(calls) return r } func callnew(t *types.Type) *ir.Node { dowidth(t) n := ir.Nod(ir.ONEWOBJ, typename(t), nil) - n.Type = types.NewPtr(t) + n.SetType(types.NewPtr(t)) n.SetTypecheck(1) n.MarkNonNil() return n @@ -2049,54 +2049,54 @@ func callnew(t *types.Type) *ir.Node { // isReflectHeaderDataField reports whether l is an expression p.Data // where p has type reflect.SliceHeader or reflect.StringHeader. func isReflectHeaderDataField(l *ir.Node) bool { - if l.Type != types.Types[types.TUINTPTR] { + if l.Type() != types.Types[types.TUINTPTR] { return false } var tsym *types.Sym - switch l.Op { + switch l.Op() { case ir.ODOT: - tsym = l.Left.Type.Sym + tsym = l.Left().Type().Sym case ir.ODOTPTR: - tsym = l.Left.Type.Elem().Sym + tsym = l.Left().Type().Elem().Sym default: return false } - if tsym == nil || l.Sym.Name != "Data" || tsym.Pkg.Path != "reflect" { + if tsym == nil || l.Sym().Name != "Data" || tsym.Pkg.Path != "reflect" { return false } return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader" } func convas(n *ir.Node, init *ir.Nodes) *ir.Node { - if n.Op != ir.OAS { - base.Fatalf("convas: not OAS %v", n.Op) + if n.Op() != ir.OAS { + base.Fatalf("convas: not OAS %v", n.Op()) } defer updateHasCall(n) n.SetTypecheck(1) - if n.Left == nil || n.Right == nil { + if n.Left() == nil || n.Right() == nil { return n } - lt := n.Left.Type - rt := n.Right.Type + lt := n.Left().Type() + rt := n.Right().Type() if lt == nil || rt == nil { return n } - if ir.IsBlank(n.Left) { - n.Right = defaultlit(n.Right, nil) + if ir.IsBlank(n.Left()) { + n.SetRight(defaultlit(n.Right(), nil)) return n } if !types.Identical(lt, rt) { - n.Right = assignconv(n.Right, lt, "assignment") - n.Right = walkexpr(n.Right, init) + n.SetRight(assignconv(n.Right(), lt, "assignment")) + n.SetRight(walkexpr(n.Right(), init)) } - dowidth(n.Right.Type) + dowidth(n.Right().Type()) return n } @@ -2115,45 +2115,45 @@ func reorder3(all []*ir.Node) []*ir.Node { var mapinit ir.Nodes for i, n := range all { - l := n.Left + l := n.Left() // Save subexpressions needed on left side. // Drill through non-dereferences. for { - if l.Op == ir.ODOT || l.Op == ir.OPAREN { - l = l.Left + if l.Op() == ir.ODOT || l.Op() == ir.OPAREN { + l = l.Left() continue } - if l.Op == ir.OINDEX && l.Left.Type.IsArray() { - l.Right = reorder3save(l.Right, all, i, &early) - l = l.Left + if l.Op() == ir.OINDEX && l.Left().Type().IsArray() { + l.SetRight(reorder3save(l.Right(), all, i, &early)) + l = l.Left() continue } break } - switch l.Op { + switch l.Op() { default: - base.Fatalf("reorder3 unexpected lvalue %#v", l.Op) + base.Fatalf("reorder3 unexpected lvalue %#v", l.Op()) case ir.ONAME: break case ir.OINDEX, ir.OINDEXMAP: - l.Left = reorder3save(l.Left, all, i, &early) - l.Right = reorder3save(l.Right, all, i, &early) - if l.Op == ir.OINDEXMAP { + l.SetLeft(reorder3save(l.Left(), all, i, &early)) + l.SetRight(reorder3save(l.Right(), all, i, &early)) + if l.Op() == ir.OINDEXMAP { all[i] = convas(all[i], &mapinit) } case ir.ODEREF, ir.ODOTPTR: - l.Left = reorder3save(l.Left, all, i, &early) + l.SetLeft(reorder3save(l.Left(), all, i, &early)) } // Save expression on right side. - all[i].Right = reorder3save(all[i].Right, all, i, &early) + all[i].SetRight(reorder3save(all[i].Right(), all, i, &early)) } early = append(mapinit.Slice(), early...) @@ -2171,26 +2171,26 @@ func reorder3save(n *ir.Node, all []*ir.Node, i int, early *[]*ir.Node) *ir.Node return n } - q := temp(n.Type) + q := temp(n.Type()) q = ir.Nod(ir.OAS, q, n) q = typecheck(q, ctxStmt) *early = append(*early, q) - return q.Left + return q.Left() } // what's the outer value that a write to n affects? // outer value means containing struct or array. func outervalue(n *ir.Node) *ir.Node { for { - switch n.Op { + switch n.Op() { case ir.OXDOT: base.Fatalf("OXDOT in walk") case ir.ODOT, ir.OPAREN, ir.OCONVNOP: - n = n.Left + n = n.Left() continue case ir.OINDEX: - if n.Left.Type != nil && n.Left.Type.IsArray() { - n = n.Left + if n.Left().Type() != nil && n.Left().Type().IsArray() { + n = n.Left() continue } } @@ -2208,8 +2208,8 @@ func aliased(r *ir.Node, all []*ir.Node) bool { // Treat all fields of a struct as referring to the whole struct. // We could do better but we would have to keep track of the fields. - for r.Op == ir.ODOT { - r = r.Left + for r.Op() == ir.ODOT { + r = r.Left() } // Look for obvious aliasing: a variable being assigned @@ -2220,12 +2220,12 @@ func aliased(r *ir.Node, all []*ir.Node) bool { memwrite := false for _, as := range all { // We can ignore assignments to blank. - if ir.IsBlank(as.Left) { + if ir.IsBlank(as.Left()) { continue } - l := outervalue(as.Left) - if l.Op != ir.ONAME { + l := outervalue(as.Left()) + if l.Op() != ir.ONAME { memwrite = true continue } @@ -2239,7 +2239,7 @@ func aliased(r *ir.Node, all []*ir.Node) bool { continue case ir.PAUTO, ir.PPARAM, ir.PPARAMOUT: - if l.Name.Addrtaken() { + if l.Name().Addrtaken() { memwrite = true continue } @@ -2280,14 +2280,14 @@ func varexpr(n *ir.Node) bool { return true } - switch n.Op { + switch n.Op() { case ir.OLITERAL, ir.ONIL: return true case ir.ONAME: switch n.Class() { case ir.PAUTO, ir.PPARAM, ir.PPARAMOUT: - if !n.Name.Addrtaken() { + if !n.Name().Addrtaken() { return true } } @@ -2315,7 +2315,7 @@ func varexpr(n *ir.Node) bool { ir.OCONVNOP, ir.OCONVIFACE, ir.ODOTTYPE: - return varexpr(n.Left) && varexpr(n.Right) + return varexpr(n.Left()) && varexpr(n.Right()) case ir.ODOT: // but not ODOTPTR // Should have been handled in aliased. @@ -2331,7 +2331,7 @@ func vmatch2(l *ir.Node, r *ir.Node) bool { if r == nil { return false } - switch r.Op { + switch r.Op() { // match each right given left case ir.ONAME: return l == r @@ -2340,13 +2340,13 @@ func vmatch2(l *ir.Node, r *ir.Node) bool { return false } - if vmatch2(l, r.Left) { + if vmatch2(l, r.Left()) { return true } - if vmatch2(l, r.Right) { + if vmatch2(l, r.Right()) { return true } - for _, n := range r.List.Slice() { + for _, n := range r.List().Slice() { if vmatch2(l, n) { return true } @@ -2361,7 +2361,7 @@ func vmatch1(l *ir.Node, r *ir.Node) bool { if l == nil || r == nil { return false } - switch l.Op { + switch l.Op() { case ir.ONAME: switch l.Class() { case ir.PPARAM, ir.PAUTO: @@ -2381,13 +2381,13 @@ func vmatch1(l *ir.Node, r *ir.Node) bool { return false } - if vmatch1(l.Left, r) { + if vmatch1(l.Left(), r) { return true } - if vmatch1(l.Right, r) { + if vmatch1(l.Right(), r) { return true } - for _, n := range l.List.Slice() { + for _, n := range l.List().Slice() { if vmatch1(n, r) { return true } @@ -2401,14 +2401,14 @@ func paramstoheap(params *types.Type) []*ir.Node { var nn []*ir.Node for _, t := range params.Fields().Slice() { v := ir.AsNode(t.Nname) - if v != nil && v.Sym != nil && strings.HasPrefix(v.Sym.Name, "~r") { // unnamed result + if v != nil && v.Sym() != nil && strings.HasPrefix(v.Sym().Name, "~r") { // unnamed result v = nil } if v == nil { continue } - if stackcopy := v.Name.Param.Stackcopy; stackcopy != nil { + if stackcopy := v.Name().Param.Stackcopy; stackcopy != nil { nn = append(nn, walkstmt(ir.Nod(ir.ODCL, v, nil))) if stackcopy.Class() == ir.PPARAM { nn = append(nn, walkstmt(typecheck(ir.Nod(ir.OAS, v, stackcopy), ctxStmt))) @@ -2427,9 +2427,9 @@ func paramstoheap(params *types.Type) []*ir.Node { // even allocations to move params/results to the heap. // The generated code is added to Curfn's Enter list. func zeroResults() { - for _, f := range Curfn.Type.Results().Fields().Slice() { + for _, f := range Curfn.Type().Results().Fields().Slice() { v := ir.AsNode(f.Nname) - if v != nil && v.Name.Param.Heapaddr != nil { + if v != nil && v.Name().Param.Heapaddr != nil { // The local which points to the return value is the // thing that needs zeroing. This is already handled // by a Needzero annotation in plive.go:livenessepilogue. @@ -2442,10 +2442,10 @@ func zeroResults() { // I don't think the zeroing below matters. // The stack return value will never be marked as live anywhere in the function. // It is not written to until deferreturn returns. - v = v.Name.Param.Stackcopy + v = v.Name().Param.Stackcopy } // Zero the stack location containing f. - Curfn.Func.Enter.Append(ir.NodAt(Curfn.Pos, ir.OAS, v, nil)) + Curfn.Func().Enter.Append(ir.NodAt(Curfn.Pos(), ir.OAS, v, nil)) } } @@ -2458,7 +2458,7 @@ func returnsfromheap(params *types.Type) []*ir.Node { if v == nil { continue } - if stackcopy := v.Name.Param.Stackcopy; stackcopy != nil && stackcopy.Class() == ir.PPARAMOUT { + if stackcopy := v.Name().Param.Stackcopy; stackcopy != nil && stackcopy.Class() == ir.PPARAMOUT { nn = append(nn, walkstmt(typecheck(ir.Nod(ir.OAS, stackcopy, v), ctxStmt))) } } @@ -2471,35 +2471,35 @@ func returnsfromheap(params *types.Type) []*ir.Node { // Enter and Exit lists. func heapmoves() { lno := base.Pos - base.Pos = Curfn.Pos - nn := paramstoheap(Curfn.Type.Recvs()) - nn = append(nn, paramstoheap(Curfn.Type.Params())...) - nn = append(nn, paramstoheap(Curfn.Type.Results())...) - Curfn.Func.Enter.Append(nn...) - base.Pos = Curfn.Func.Endlineno - Curfn.Func.Exit.Append(returnsfromheap(Curfn.Type.Results())...) + base.Pos = Curfn.Pos() + nn := paramstoheap(Curfn.Type().Recvs()) + nn = append(nn, paramstoheap(Curfn.Type().Params())...) + nn = append(nn, paramstoheap(Curfn.Type().Results())...) + Curfn.Func().Enter.Append(nn...) + base.Pos = Curfn.Func().Endlineno + Curfn.Func().Exit.Append(returnsfromheap(Curfn.Type().Results())...) base.Pos = lno } func vmkcall(fn *ir.Node, t *types.Type, init *ir.Nodes, va []*ir.Node) *ir.Node { - if fn.Type == nil || fn.Type.Etype != types.TFUNC { - base.Fatalf("mkcall %v %v", fn, fn.Type) + if fn.Type() == nil || fn.Type().Etype != types.TFUNC { + base.Fatalf("mkcall %v %v", fn, fn.Type()) } - n := fn.Type.NumParams() + n := fn.Type().NumParams() if n != len(va) { base.Fatalf("vmkcall %v needs %v args got %v", fn, n, len(va)) } r := ir.Nod(ir.OCALL, fn, nil) - r.List.Set(va) - if fn.Type.NumResults() > 0 { + r.PtrList().Set(va) + if fn.Type().NumResults() > 0 { r = typecheck(r, ctxExpr|ctxMultiOK) } else { r = typecheck(r, ctxStmt) } r = walkexpr(r, init) - r.Type = t + r.SetType(t) return r } @@ -2512,11 +2512,11 @@ func mkcall1(fn *ir.Node, t *types.Type, init *ir.Nodes, args ...*ir.Node) *ir.N } func conv(n *ir.Node, t *types.Type) *ir.Node { - if types.Identical(n.Type, t) { + if types.Identical(n.Type(), t) { return n } n = ir.Nod(ir.OCONV, n, nil) - n.Type = t + n.SetType(t) n = typecheck(n, ctxExpr) return n } @@ -2524,11 +2524,11 @@ func conv(n *ir.Node, t *types.Type) *ir.Node { // convnop converts node n to type t using the OCONVNOP op // and typechecks the result with ctxExpr. func convnop(n *ir.Node, t *types.Type) *ir.Node { - if types.Identical(n.Type, t) { + if types.Identical(n.Type(), t) { return n } n = ir.Nod(ir.OCONVNOP, n, nil) - n.Type = t + n.SetType(t) n = typecheck(n, ctxExpr) return n } @@ -2541,13 +2541,13 @@ func byteindex(n *ir.Node) *ir.Node { // While converting from int8 to int is possible, it would yield // the wrong result for negative values. // Reinterpreting the value as an unsigned byte solves both cases. - if !types.Identical(n.Type, types.Types[types.TUINT8]) { + if !types.Identical(n.Type(), types.Types[types.TUINT8]) { n = ir.Nod(ir.OCONV, n, nil) - n.Type = types.Types[types.TUINT8] + n.SetType(types.Types[types.TUINT8]) n.SetTypecheck(1) } n = ir.Nod(ir.OCONV, n, nil) - n.Type = types.Types[types.TINT] + n.SetType(types.Types[types.TINT]) n.SetTypecheck(1) return n } @@ -2644,17 +2644,17 @@ func writebarrierfn(name string, l *types.Type, r *types.Type) *ir.Node { func addstr(n *ir.Node, init *ir.Nodes) *ir.Node { // order.expr rewrote OADDSTR to have a list of strings. - c := n.List.Len() + c := n.List().Len() if c < 2 { base.Fatalf("addstr count %d too small", c) } buf := nodnil() - if n.Esc == EscNone { + if n.Esc() == EscNone { sz := int64(0) - for _, n1 := range n.List.Slice() { - if n1.Op == ir.OLITERAL { + for _, n1 := range n.List().Slice() { + if n1.Op() == ir.OLITERAL { sz += int64(len(n1.StringVal())) } } @@ -2669,7 +2669,7 @@ func addstr(n *ir.Node, init *ir.Nodes) *ir.Node { // build list of string arguments args := []*ir.Node{buf} - for _, n2 := range n.List.Slice() { + for _, n2 := range n.List().Slice() { args = append(args, conv(n2, types.Types[types.TSTRING])) } @@ -2687,28 +2687,28 @@ func addstr(n *ir.Node, init *ir.Nodes) *ir.Node { if prealloc[n] != nil { prealloc[slice] = prealloc[n] } - slice.List.Set(args[1:]) // skip buf arg + slice.PtrList().Set(args[1:]) // skip buf arg args = []*ir.Node{buf, slice} - slice.Esc = EscNone + slice.SetEsc(EscNone) } cat := syslook(fn) r := ir.Nod(ir.OCALL, cat, nil) - r.List.Set(args) + r.PtrList().Set(args) r = typecheck(r, ctxExpr) r = walkexpr(r, init) - r.Type = n.Type + r.SetType(n.Type()) return r } func walkAppendArgs(n *ir.Node, init *ir.Nodes) { - walkexprlistsafe(n.List.Slice(), init) + walkexprlistsafe(n.List().Slice(), init) // walkexprlistsafe will leave OINDEX (s[n]) alone if both s // and n are name or literal, but those may index the slice we're // modifying here. Fix explicitly. - ls := n.List.Slice() + ls := n.List().Slice() for i1, n1 := range ls { ls[i1] = cheapexpr(n1, init) } @@ -2731,18 +2731,18 @@ func walkAppendArgs(n *ir.Node, init *ir.Nodes) { func appendslice(n *ir.Node, init *ir.Nodes) *ir.Node { walkAppendArgs(n, init) - l1 := n.List.First() - l2 := n.List.Second() + l1 := n.List().First() + l2 := n.List().Second() l2 = cheapexpr(l2, init) - n.List.SetSecond(l2) + n.List().SetSecond(l2) var nodes ir.Nodes // var s []T - s := temp(l1.Type) + s := temp(l1.Type()) nodes.Append(ir.Nod(ir.OAS, s, l1)) // s = l1 - elemtype := s.Type.Elem() + elemtype := s.Type().Elem() // n := len(s) + len(l2) nn := temp(types.Types[types.TINT]) @@ -2752,14 +2752,14 @@ func appendslice(n *ir.Node, init *ir.Nodes) *ir.Node { nif := ir.Nod(ir.OIF, nil, nil) nuint := conv(nn, types.Types[types.TUINT]) scapuint := conv(ir.Nod(ir.OCAP, s, nil), types.Types[types.TUINT]) - nif.Left = ir.Nod(ir.OGT, nuint, scapuint) + nif.SetLeft(ir.Nod(ir.OGT, nuint, scapuint)) // instantiate growslice(typ *type, []any, int) []any fn := syslook("growslice") fn = substArgTypes(fn, elemtype, elemtype) // s = growslice(T, s, n) - nif.Nbody.Set1(ir.Nod(ir.OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(elemtype), s, nn))) + nif.PtrBody().Set1(ir.Nod(ir.OAS, s, mkcall1(fn, s.Type(), nif.PtrInit(), typename(elemtype), s, nn))) nodes.Append(nif) // s = s[:n] @@ -2772,17 +2772,17 @@ func appendslice(n *ir.Node, init *ir.Nodes) *ir.Node { if elemtype.HasPointers() { // copy(s[len(l1):], l2) nptr1 := ir.Nod(ir.OSLICE, s, nil) - nptr1.Type = s.Type + nptr1.SetType(s.Type()) nptr1.SetSliceBounds(ir.Nod(ir.OLEN, l1, nil), nil, nil) nptr1 = cheapexpr(nptr1, &nodes) nptr2 := l2 - Curfn.Func.SetWBPos(n.Pos) + Curfn.Func().SetWBPos(n.Pos()) // instantiate typedslicecopy(typ *type, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int fn := syslook("typedslicecopy") - fn = substArgTypes(fn, l1.Type.Elem(), l2.Type.Elem()) + fn = substArgTypes(fn, l1.Type().Elem(), l2.Type().Elem()) ptr1, len1 := backingArrayPtrLen(nptr1) ptr2, len2 := backingArrayPtrLen(nptr2) ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, typename(elemtype), ptr1, len1, ptr2, len2) @@ -2791,7 +2791,7 @@ func appendslice(n *ir.Node, init *ir.Nodes) *ir.Node { // copy(s[len(l1):], l2) // l2 can be a slice or string. nptr1 := ir.Nod(ir.OSLICE, s, nil) - nptr1.Type = s.Type + nptr1.SetType(s.Type()) nptr1.SetSliceBounds(ir.Nod(ir.OLEN, l1, nil), nil, nil) nptr1 = cheapexpr(nptr1, &nodes) nptr2 := l2 @@ -2800,7 +2800,7 @@ func appendslice(n *ir.Node, init *ir.Nodes) *ir.Node { ptr2, len2 := backingArrayPtrLen(nptr2) fn := syslook("slicecopy") - fn = substArgTypes(fn, ptr1.Type.Elem(), ptr2.Type.Elem()) + fn = substArgTypes(fn, ptr1.Type().Elem(), ptr2.Type().Elem()) ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, ptr1, len1, ptr2, len2, nodintconst(elemtype.Width)) } else { // memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T)) @@ -2837,12 +2837,12 @@ func isAppendOfMake(n *ir.Node) bool { base.Fatalf("missing typecheck: %+v", n) } - if n.Op != ir.OAPPEND || !n.IsDDD() || n.List.Len() != 2 { + if n.Op() != ir.OAPPEND || !n.IsDDD() || n.List().Len() != 2 { return false } - second := n.List.Second() - if second.Op != ir.OMAKESLICE || second.Right != nil { + second := n.List().Second() + if second.Op() != ir.OMAKESLICE || second.Right() != nil { return false } @@ -2852,8 +2852,8 @@ func isAppendOfMake(n *ir.Node) bool { // typecheck made sure that constant arguments to make are not negative and fit into an int. // The care of overflow of the len argument to make will be handled by an explicit check of int(len) < 0 during runtime. - y := second.Left - if !ir.IsConst(y, constant.Int) && y.Type.Size() > types.Types[types.TUINT].Size() { + y := second.Left() + if !ir.IsConst(y, constant.Int) && y.Type().Size() > types.Types[types.TUINT].Size() { return false } @@ -2891,14 +2891,14 @@ func extendslice(n *ir.Node, init *ir.Nodes) *ir.Node { // isAppendOfMake made sure all possible positive values of l2 fit into an uint. // The case of l2 overflow when converting from e.g. uint to int is handled by an explicit // check of l2 < 0 at runtime which is generated below. - l2 := conv(n.List.Second().Left, types.Types[types.TINT]) + l2 := conv(n.List().Second().Left(), types.Types[types.TINT]) l2 = typecheck(l2, ctxExpr) - n.List.SetSecond(l2) // walkAppendArgs expects l2 in n.List.Second(). + n.List().SetSecond(l2) // walkAppendArgs expects l2 in n.List.Second(). walkAppendArgs(n, init) - l1 := n.List.First() - l2 = n.List.Second() // re-read l2, as it may have been updated by walkAppendArgs + l1 := n.List().First() + l2 = n.List().Second() // re-read l2, as it may have been updated by walkAppendArgs var nodes []*ir.Node @@ -2907,14 +2907,14 @@ func extendslice(n *ir.Node, init *ir.Nodes) *ir.Node { nifneg.SetLikely(true) // else panicmakeslicelen() - nifneg.Rlist.Set1(mkcall("panicmakeslicelen", nil, init)) + nifneg.PtrRlist().Set1(mkcall("panicmakeslicelen", nil, init)) nodes = append(nodes, nifneg) // s := l1 - s := temp(l1.Type) + s := temp(l1.Type()) nodes = append(nodes, ir.Nod(ir.OAS, s, l1)) - elemtype := s.Type.Elem() + elemtype := s.Type().Elem() // n := len(s) + l2 nn := temp(types.Types[types.TINT]) @@ -2930,7 +2930,7 @@ func extendslice(n *ir.Node, init *ir.Nodes) *ir.Node { fn = substArgTypes(fn, elemtype, elemtype) // s = growslice(T, s, n) - nif.Nbody.Set1(ir.Nod(ir.OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(elemtype), s, nn))) + nif.PtrBody().Set1(ir.Nod(ir.OAS, s, mkcall1(fn, s.Type(), nif.PtrInit(), typename(elemtype), s, nn))) nodes = append(nodes, nif) // s = s[:n] @@ -2940,7 +2940,7 @@ func extendslice(n *ir.Node, init *ir.Nodes) *ir.Node { nodes = append(nodes, ir.Nod(ir.OAS, s, nt)) // lptr := &l1[0] - l1ptr := temp(l1.Type.Elem().PtrTo()) + l1ptr := temp(l1.Type().Elem().PtrTo()) tmp := ir.Nod(ir.OSPTR, l1, nil) nodes = append(nodes, ir.Nod(ir.OAS, l1ptr, tmp)) @@ -2963,7 +2963,7 @@ func extendslice(n *ir.Node, init *ir.Nodes) *ir.Node { hasPointers := elemtype.HasPointers() if hasPointers { clrname = "memclrHasPointers" - Curfn.Func.SetWBPos(n.Pos) + Curfn.Func().SetWBPos(n.Pos()) } var clr ir.Nodes @@ -2973,7 +2973,7 @@ func extendslice(n *ir.Node, init *ir.Nodes) *ir.Node { if hasPointers { // if l1ptr == sptr nifclr := ir.Nod(ir.OIF, ir.Nod(ir.OEQ, l1ptr, sptr), nil) - nifclr.Nbody = clr + nifclr.SetBody(clr) nodes = append(nodes, nifclr) } else { nodes = append(nodes, clr.Slice()...) @@ -3007,13 +3007,13 @@ func extendslice(n *ir.Node, init *ir.Nodes) *ir.Node { // } // s func walkappend(n *ir.Node, init *ir.Nodes, dst *ir.Node) *ir.Node { - if !samesafeexpr(dst, n.List.First()) { - n.List.SetFirst(safeexpr(n.List.First(), init)) - n.List.SetFirst(walkexpr(n.List.First(), init)) + if !samesafeexpr(dst, n.List().First()) { + n.List().SetFirst(safeexpr(n.List().First(), init)) + n.List().SetFirst(walkexpr(n.List().First(), init)) } - walkexprlistsafe(n.List.Slice()[1:], init) + walkexprlistsafe(n.List().Slice()[1:], init) - nsrc := n.List.First() + nsrc := n.List().First() // walkexprlistsafe will leave OINDEX (s[n]) alone if both s // and n are name or literal, but those may index the slice we're @@ -3021,17 +3021,17 @@ func walkappend(n *ir.Node, init *ir.Nodes, dst *ir.Node) *ir.Node { // Using cheapexpr also makes sure that the evaluation // of all arguments (and especially any panics) happen // before we begin to modify the slice in a visible way. - ls := n.List.Slice()[1:] + ls := n.List().Slice()[1:] for i, n := range ls { n = cheapexpr(n, init) - if !types.Identical(n.Type, nsrc.Type.Elem()) { - n = assignconv(n, nsrc.Type.Elem(), "append") + if !types.Identical(n.Type(), nsrc.Type().Elem()) { + n = assignconv(n, nsrc.Type().Elem(), "append") n = walkexpr(n, init) } ls[i] = n } - argc := n.List.Len() - 1 + argc := n.List().Len() - 1 if argc < 1 { return nsrc } @@ -3044,18 +3044,18 @@ func walkappend(n *ir.Node, init *ir.Nodes, dst *ir.Node) *ir.Node { var l []*ir.Node - ns := temp(nsrc.Type) + ns := temp(nsrc.Type()) l = append(l, ir.Nod(ir.OAS, ns, nsrc)) // s = src na := nodintconst(int64(argc)) // const argc nx := ir.Nod(ir.OIF, nil, nil) // if cap(s) - len(s) < argc - nx.Left = ir.Nod(ir.OLT, ir.Nod(ir.OSUB, ir.Nod(ir.OCAP, ns, nil), ir.Nod(ir.OLEN, ns, nil)), na) + nx.SetLeft(ir.Nod(ir.OLT, ir.Nod(ir.OSUB, ir.Nod(ir.OCAP, ns, nil), ir.Nod(ir.OLEN, ns, nil)), na)) fn := syslook("growslice") // growslice(, old []T, mincap int) (ret []T) - fn = substArgTypes(fn, ns.Type.Elem(), ns.Type.Elem()) + fn = substArgTypes(fn, ns.Type().Elem(), ns.Type().Elem()) - nx.Nbody.Set1(ir.Nod(ir.OAS, ns, - mkcall1(fn, ns.Type, &nx.Ninit, typename(ns.Type.Elem()), ns, + nx.PtrBody().Set1(ir.Nod(ir.OAS, ns, + mkcall1(fn, ns.Type(), nx.PtrInit(), typename(ns.Type().Elem()), ns, ir.Nod(ir.OADD, ir.Nod(ir.OLEN, ns, nil), na)))) l = append(l, nx) @@ -3068,7 +3068,7 @@ func walkappend(n *ir.Node, init *ir.Nodes, dst *ir.Node) *ir.Node { nx.SetBounded(true) l = append(l, ir.Nod(ir.OAS, ns, nx)) // s = s[:n+argc] - ls = n.List.Slice()[1:] + ls = n.List().Slice()[1:] for i, n := range ls { nx = ir.Nod(ir.OINDEX, ns, nn) // s[n] ... nx.SetBounded(true) @@ -3096,14 +3096,14 @@ func walkappend(n *ir.Node, init *ir.Nodes, dst *ir.Node) *ir.Node { // Also works if b is a string. // func copyany(n *ir.Node, init *ir.Nodes, runtimecall bool) *ir.Node { - if n.Left.Type.Elem().HasPointers() { - Curfn.Func.SetWBPos(n.Pos) - fn := writebarrierfn("typedslicecopy", n.Left.Type.Elem(), n.Right.Type.Elem()) - n.Left = cheapexpr(n.Left, init) - ptrL, lenL := backingArrayPtrLen(n.Left) - n.Right = cheapexpr(n.Right, init) - ptrR, lenR := backingArrayPtrLen(n.Right) - return mkcall1(fn, n.Type, init, typename(n.Left.Type.Elem()), ptrL, lenL, ptrR, lenR) + if n.Left().Type().Elem().HasPointers() { + Curfn.Func().SetWBPos(n.Pos()) + fn := writebarrierfn("typedslicecopy", n.Left().Type().Elem(), n.Right().Type().Elem()) + n.SetLeft(cheapexpr(n.Left(), init)) + ptrL, lenL := backingArrayPtrLen(n.Left()) + n.SetRight(cheapexpr(n.Right(), init)) + ptrR, lenR := backingArrayPtrLen(n.Right()) + return mkcall1(fn, n.Type(), init, typename(n.Left().Type().Elem()), ptrL, lenL, ptrR, lenR) } if runtimecall { @@ -3111,24 +3111,24 @@ func copyany(n *ir.Node, init *ir.Nodes, runtimecall bool) *ir.Node { // copy(n.Left, n.Right) // n.Right can be a slice or string. - n.Left = cheapexpr(n.Left, init) - ptrL, lenL := backingArrayPtrLen(n.Left) - n.Right = cheapexpr(n.Right, init) - ptrR, lenR := backingArrayPtrLen(n.Right) + n.SetLeft(cheapexpr(n.Left(), init)) + ptrL, lenL := backingArrayPtrLen(n.Left()) + n.SetRight(cheapexpr(n.Right(), init)) + ptrR, lenR := backingArrayPtrLen(n.Right()) fn := syslook("slicecopy") - fn = substArgTypes(fn, ptrL.Type.Elem(), ptrR.Type.Elem()) + fn = substArgTypes(fn, ptrL.Type().Elem(), ptrR.Type().Elem()) - return mkcall1(fn, n.Type, init, ptrL, lenL, ptrR, lenR, nodintconst(n.Left.Type.Elem().Width)) + return mkcall1(fn, n.Type(), init, ptrL, lenL, ptrR, lenR, nodintconst(n.Left().Type().Elem().Width)) } - n.Left = walkexpr(n.Left, init) - n.Right = walkexpr(n.Right, init) - nl := temp(n.Left.Type) - nr := temp(n.Right.Type) + n.SetLeft(walkexpr(n.Left(), init)) + n.SetRight(walkexpr(n.Right(), init)) + nl := temp(n.Left().Type()) + nr := temp(n.Right().Type()) var l []*ir.Node - l = append(l, ir.Nod(ir.OAS, nl, n.Left)) - l = append(l, ir.Nod(ir.OAS, nr, n.Right)) + l = append(l, ir.Nod(ir.OAS, nl, n.Left())) + l = append(l, ir.Nod(ir.OAS, nr, n.Right())) nfrm := ir.Nod(ir.OSPTR, nr, nil) nto := ir.Nod(ir.OSPTR, nl, nil) @@ -3141,8 +3141,8 @@ func copyany(n *ir.Node, init *ir.Nodes, runtimecall bool) *ir.Node { // if n > len(frm) { n = len(frm) } nif := ir.Nod(ir.OIF, nil, nil) - nif.Left = ir.Nod(ir.OGT, nlen, ir.Nod(ir.OLEN, nr, nil)) - nif.Nbody.Append(ir.Nod(ir.OAS, nlen, ir.Nod(ir.OLEN, nr, nil))) + nif.SetLeft(ir.Nod(ir.OGT, nlen, ir.Nod(ir.OLEN, nr, nil))) + nif.PtrBody().Append(ir.Nod(ir.OAS, nlen, ir.Nod(ir.OLEN, nr, nil))) l = append(l, nif) // if to.ptr != frm.ptr { memmove( ... ) } @@ -3151,13 +3151,13 @@ func copyany(n *ir.Node, init *ir.Nodes, runtimecall bool) *ir.Node { l = append(l, ne) fn := syslook("memmove") - fn = substArgTypes(fn, nl.Type.Elem(), nl.Type.Elem()) + fn = substArgTypes(fn, nl.Type().Elem(), nl.Type().Elem()) nwid := temp(types.Types[types.TUINTPTR]) setwid := ir.Nod(ir.OAS, nwid, conv(nlen, types.Types[types.TUINTPTR])) - ne.Nbody.Append(setwid) - nwid = ir.Nod(ir.OMUL, nwid, nodintconst(nl.Type.Elem().Width)) + ne.PtrBody().Append(setwid) + nwid = ir.Nod(ir.OMUL, nwid, nodintconst(nl.Type().Elem().Width)) call := mkcall1(fn, nil, init, nto, nfrm, nwid) - ne.Nbody.Append(call) + ne.PtrBody().Append(call) typecheckslice(l, ctxStmt) walkstmtlist(l) @@ -3179,12 +3179,12 @@ func eqfor(t *types.Type) (n *ir.Node, needsize bool) { sym := typesymprefix(".eq", t) n := NewName(sym) setNodeNameFunc(n) - n.Type = functype(nil, []*ir.Node{ + n.SetType(functype(nil, []*ir.Node{ anonfield(types.NewPtr(t)), anonfield(types.NewPtr(t)), }, []*ir.Node{ anonfield(types.Types[types.TBOOL]), - }) + })) return n, false } base.Fatalf("eqfor %v", t) @@ -3194,31 +3194,31 @@ func eqfor(t *types.Type) (n *ir.Node, needsize bool) { // The result of walkcompare MUST be assigned back to n, e.g. // n.Left = walkcompare(n.Left, init) func walkcompare(n *ir.Node, init *ir.Nodes) *ir.Node { - if n.Left.Type.IsInterface() && n.Right.Type.IsInterface() && n.Left.Op != ir.ONIL && n.Right.Op != ir.ONIL { + if n.Left().Type().IsInterface() && n.Right().Type().IsInterface() && n.Left().Op() != ir.ONIL && n.Right().Op() != ir.ONIL { return walkcompareInterface(n, init) } - if n.Left.Type.IsString() && n.Right.Type.IsString() { + if n.Left().Type().IsString() && n.Right().Type().IsString() { return walkcompareString(n, init) } - n.Left = walkexpr(n.Left, init) - n.Right = walkexpr(n.Right, init) + n.SetLeft(walkexpr(n.Left(), init)) + n.SetRight(walkexpr(n.Right(), init)) // Given mixed interface/concrete comparison, // rewrite into types-equal && data-equal. // This is efficient, avoids allocations, and avoids runtime calls. - if n.Left.Type.IsInterface() != n.Right.Type.IsInterface() { + if n.Left().Type().IsInterface() != n.Right().Type().IsInterface() { // Preserve side-effects in case of short-circuiting; see #32187. - l := cheapexpr(n.Left, init) - r := cheapexpr(n.Right, init) + l := cheapexpr(n.Left(), init) + r := cheapexpr(n.Right(), init) // Swap so that l is the interface value and r is the concrete value. - if n.Right.Type.IsInterface() { + if n.Right().Type().IsInterface() { l, r = r, l } // Handle both == and !=. - eq := n.Op + eq := n.Op() andor := ir.OOROR if eq == ir.OEQ { andor = ir.OANDAND @@ -3230,9 +3230,9 @@ func walkcompare(n *ir.Node, init *ir.Nodes) *ir.Node { // l.tab != nil && l.tab._type == type(r) var eqtype *ir.Node tab := ir.Nod(ir.OITAB, l, nil) - rtyp := typename(r.Type) - if l.Type.IsEmptyInterface() { - tab.Type = types.NewPtr(types.Types[types.TUINT8]) + rtyp := typename(r.Type()) + if l.Type().IsEmptyInterface() { + tab.SetType(types.NewPtr(types.Types[types.TUINT8])) tab.SetTypecheck(1) eqtype = ir.Nod(eq, tab, rtyp) } else { @@ -3241,7 +3241,7 @@ func walkcompare(n *ir.Node, init *ir.Nodes) *ir.Node { eqtype = ir.Nod(andor, nonnil, match) } // Check for data equal. - eqdata := ir.Nod(eq, ifaceData(n.Pos, l, r.Type), r) + eqdata := ir.Nod(eq, ifaceData(n.Pos(), l, r.Type()), r) // Put it all together. expr := ir.Nod(andor, eqtype, eqdata) n = finishcompare(n, expr, init) @@ -3252,7 +3252,7 @@ func walkcompare(n *ir.Node, init *ir.Nodes) *ir.Node { // Otherwise back end handles it. // While we're here, decide whether to // inline or call an eq alg. - t := n.Left.Type + t := n.Left().Type() var inline bool maxcmpsize := int64(4) @@ -3265,18 +3265,18 @@ func walkcompare(n *ir.Node, init *ir.Nodes) *ir.Node { switch t.Etype { default: if base.Debug.Libfuzzer != 0 && t.IsInteger() { - n.Left = cheapexpr(n.Left, init) - n.Right = cheapexpr(n.Right, init) + n.SetLeft(cheapexpr(n.Left(), init)) + n.SetRight(cheapexpr(n.Right(), init)) // If exactly one comparison operand is // constant, invoke the constcmp functions // instead, and arrange for the constant // operand to be the first argument. - l, r := n.Left, n.Right - if r.Op == ir.OLITERAL { + l, r := n.Left(), n.Right() + if r.Op() == ir.OLITERAL { l, r = r, l } - constcmp := l.Op == ir.OLITERAL && r.Op != ir.OLITERAL + constcmp := l.Op() == ir.OLITERAL && r.Op() != ir.OLITERAL var fn string var paramType *types.Type @@ -3318,13 +3318,13 @@ func walkcompare(n *ir.Node, init *ir.Nodes) *ir.Node { inline = t.NumComponents(types.IgnoreBlankFields) <= 4 } - cmpl := n.Left - for cmpl != nil && cmpl.Op == ir.OCONVNOP { - cmpl = cmpl.Left + cmpl := n.Left() + for cmpl != nil && cmpl.Op() == ir.OCONVNOP { + cmpl = cmpl.Left() } - cmpr := n.Right - for cmpr != nil && cmpr.Op == ir.OCONVNOP { - cmpr = cmpr.Left + cmpr := n.Right() + for cmpr != nil && cmpr.Op() == ir.OCONVNOP { + cmpr = cmpr.Left() } // Chose not to inline. Call equality function directly. @@ -3336,13 +3336,13 @@ func walkcompare(n *ir.Node, init *ir.Nodes) *ir.Node { fn, needsize := eqfor(t) call := ir.Nod(ir.OCALL, fn, nil) - call.List.Append(ir.Nod(ir.OADDR, cmpl, nil)) - call.List.Append(ir.Nod(ir.OADDR, cmpr, nil)) + call.PtrList().Append(ir.Nod(ir.OADDR, cmpl, nil)) + call.PtrList().Append(ir.Nod(ir.OADDR, cmpr, nil)) if needsize { - call.List.Append(nodintconst(t.Width)) + call.PtrList().Append(nodintconst(t.Width)) } res := call - if n.Op != ir.OEQ { + if n.Op() != ir.OEQ { res = ir.Nod(ir.ONOT, res, nil) } n = finishcompare(n, res, init) @@ -3351,12 +3351,12 @@ func walkcompare(n *ir.Node, init *ir.Nodes) *ir.Node { // inline: build boolean expression comparing element by element andor := ir.OANDAND - if n.Op == ir.ONE { + if n.Op() == ir.ONE { andor = ir.OOROR } var expr *ir.Node compare := func(el, er *ir.Node) { - a := ir.Nod(n.Op, el, er) + a := ir.Nod(n.Op(), el, er) if expr == nil { expr = a } else { @@ -3433,10 +3433,10 @@ func walkcompare(n *ir.Node, init *ir.Nodes) *ir.Node { } } if expr == nil { - expr = nodbool(n.Op == ir.OEQ) + expr = nodbool(n.Op() == ir.OEQ) // We still need to use cmpl and cmpr, in case they contain // an expression which might panic. See issue 23837. - t := temp(cmpl.Type) + t := temp(cmpl.Type()) a1 := ir.Nod(ir.OAS, t, cmpl) a1 = typecheck(a1, ctxStmt) a2 := ir.Nod(ir.OAS, t, cmpr) @@ -3449,22 +3449,22 @@ func walkcompare(n *ir.Node, init *ir.Nodes) *ir.Node { func tracecmpArg(n *ir.Node, t *types.Type, init *ir.Nodes) *ir.Node { // Ugly hack to avoid "constant -1 overflows uintptr" errors, etc. - if n.Op == ir.OLITERAL && n.Type.IsSigned() && n.Int64Val() < 0 { - n = copyexpr(n, n.Type, init) + if n.Op() == ir.OLITERAL && n.Type().IsSigned() && n.Int64Val() < 0 { + n = copyexpr(n, n.Type(), init) } return conv(n, t) } func walkcompareInterface(n *ir.Node, init *ir.Nodes) *ir.Node { - n.Right = cheapexpr(n.Right, init) - n.Left = cheapexpr(n.Left, init) - eqtab, eqdata := eqinterface(n.Left, n.Right) + n.SetRight(cheapexpr(n.Right(), init)) + n.SetLeft(cheapexpr(n.Left(), init)) + eqtab, eqdata := eqinterface(n.Left(), n.Right()) var cmp *ir.Node - if n.Op == ir.OEQ { + if n.Op() == ir.OEQ { cmp = ir.Nod(ir.OANDAND, eqtab, eqdata) } else { - eqtab.Op = ir.ONE + eqtab.SetOp(ir.ONE) cmp = ir.Nod(ir.OOROR, eqtab, ir.Nod(ir.ONOT, eqdata, nil)) } return finishcompare(n, cmp, init) @@ -3474,21 +3474,21 @@ func walkcompareString(n *ir.Node, init *ir.Nodes) *ir.Node { // Rewrite comparisons to short constant strings as length+byte-wise comparisons. var cs, ncs *ir.Node // const string, non-const string switch { - case ir.IsConst(n.Left, constant.String) && ir.IsConst(n.Right, constant.String): + case ir.IsConst(n.Left(), constant.String) && ir.IsConst(n.Right(), constant.String): // ignore; will be constant evaluated - case ir.IsConst(n.Left, constant.String): - cs = n.Left - ncs = n.Right - case ir.IsConst(n.Right, constant.String): - cs = n.Right - ncs = n.Left + case ir.IsConst(n.Left(), constant.String): + cs = n.Left() + ncs = n.Right() + case ir.IsConst(n.Right(), constant.String): + cs = n.Right() + ncs = n.Left() } if cs != nil { - cmp := n.Op + cmp := n.Op() // Our comparison below assumes that the non-constant string // is on the left hand side, so rewrite "" cmp x to x cmp "". // See issue 24817. - if ir.IsConst(n.Left, constant.String) { + if ir.IsConst(n.Left(), constant.String) { cmp = brrev(cmp) } @@ -3571,25 +3571,25 @@ func walkcompareString(n *ir.Node, init *ir.Nodes) *ir.Node { } var r *ir.Node - if n.Op == ir.OEQ || n.Op == ir.ONE { + if n.Op() == ir.OEQ || n.Op() == ir.ONE { // prepare for rewrite below - n.Left = cheapexpr(n.Left, init) - n.Right = cheapexpr(n.Right, init) - eqlen, eqmem := eqstring(n.Left, n.Right) + n.SetLeft(cheapexpr(n.Left(), init)) + n.SetRight(cheapexpr(n.Right(), init)) + eqlen, eqmem := eqstring(n.Left(), n.Right()) // quick check of len before full compare for == or !=. // memequal then tests equality up to length len. - if n.Op == ir.OEQ { + if n.Op() == ir.OEQ { // len(left) == len(right) && memequal(left, right, len) r = ir.Nod(ir.OANDAND, eqlen, eqmem) } else { // len(left) != len(right) || !memequal(left, right, len) - eqlen.Op = ir.ONE + eqlen.SetOp(ir.ONE) r = ir.Nod(ir.OOROR, eqlen, ir.Nod(ir.ONOT, eqmem, nil)) } } else { // sys_cmpstring(s1, s2) :: 0 - r = mkcall("cmpstring", types.Types[types.TINT], init, conv(n.Left, types.Types[types.TSTRING]), conv(n.Right, types.Types[types.TSTRING])) - r = ir.Nod(n.Op, r, nodintconst(0)) + r = mkcall("cmpstring", types.Types[types.TINT], init, conv(n.Left(), types.Types[types.TSTRING]), conv(n.Right(), types.Types[types.TSTRING])) + r = ir.Nod(n.Op(), r, nodintconst(0)) } return finishcompare(n, r, init) @@ -3599,34 +3599,34 @@ func walkcompareString(n *ir.Node, init *ir.Nodes) *ir.Node { // n.Left = finishcompare(n.Left, x, r, init) func finishcompare(n, r *ir.Node, init *ir.Nodes) *ir.Node { r = typecheck(r, ctxExpr) - r = conv(r, n.Type) + r = conv(r, n.Type()) r = walkexpr(r, init) return r } // return 1 if integer n must be in range [0, max), 0 otherwise func bounded(n *ir.Node, max int64) bool { - if n.Type == nil || !n.Type.IsInteger() { + if n.Type() == nil || !n.Type().IsInteger() { return false } - sign := n.Type.IsSigned() - bits := int32(8 * n.Type.Width) + sign := n.Type().IsSigned() + bits := int32(8 * n.Type().Width) if smallintconst(n) { v := n.Int64Val() return 0 <= v && v < max } - switch n.Op { + switch n.Op() { case ir.OAND, ir.OANDNOT: v := int64(-1) switch { - case smallintconst(n.Left): - v = n.Left.Int64Val() - case smallintconst(n.Right): - v = n.Right.Int64Val() - if n.Op == ir.OANDNOT { + case smallintconst(n.Left()): + v = n.Left().Int64Val() + case smallintconst(n.Right()): + v = n.Right().Int64Val() + if n.Op() == ir.OANDNOT { v = ^v if !sign { v &= 1< 0 && v >= 2 { bits-- v >>= 1 @@ -3655,8 +3655,8 @@ func bounded(n *ir.Node, max int64) bool { } case ir.ORSH: - if !sign && smallintconst(n.Right) { - v := n.Right.Int64Val() + if !sign && smallintconst(n.Right()) { + v := n.Right().Int64Val() if v > int64(bits) { return true } @@ -3673,7 +3673,7 @@ func bounded(n *ir.Node, max int64) bool { // usemethod checks interface method calls for uses of reflect.Type.Method. func usemethod(n *ir.Node) { - t := n.Left.Type + t := n.Left().Type() // Looking for either of: // Method(int) reflect.Method @@ -3711,9 +3711,9 @@ func usemethod(n *ir.Node) { // (including global variables such as numImports - was issue #19028). // Also need to check for reflect package itself (see Issue #38515). if s := res0.Type.Sym; s != nil && s.Name == "Method" && isReflectPkg(s.Pkg) { - Curfn.Func.SetReflectMethod(true) + Curfn.Func().SetReflectMethod(true) // The LSym is initialized at this point. We need to set the attribute on the LSym. - Curfn.Func.LSym.Set(obj.AttrReflectMethod, true) + Curfn.Func().LSym.Set(obj.AttrReflectMethod, true) } } @@ -3722,35 +3722,35 @@ func usefield(n *ir.Node) { return } - switch n.Op { + switch n.Op() { default: - base.Fatalf("usefield %v", n.Op) + base.Fatalf("usefield %v", n.Op()) case ir.ODOT, ir.ODOTPTR: break } - if n.Sym == nil { + if n.Sym() == nil { // No field name. This DOTPTR was built by the compiler for access // to runtime data structures. Ignore. return } - t := n.Left.Type + t := n.Left().Type() if t.IsPtr() { t = t.Elem() } field := n.Opt().(*types.Field) if field == nil { - base.Fatalf("usefield %v %v without paramfld", n.Left.Type, n.Sym) + base.Fatalf("usefield %v %v without paramfld", n.Left().Type(), n.Sym()) } - if field.Sym != n.Sym || field.Offset != n.Xoffset { - base.Fatalf("field inconsistency: %v,%v != %v,%v", field.Sym, field.Offset, n.Sym, n.Xoffset) + if field.Sym != n.Sym() || field.Offset != n.Offset() { + base.Fatalf("field inconsistency: %v,%v != %v,%v", field.Sym, field.Offset, n.Sym(), n.Offset()) } if !strings.Contains(field.Note, "go:\"track\"") { return } - outer := n.Left.Type + outer := n.Left().Type() if outer.IsPtr() { outer = outer.Elem() } @@ -3762,10 +3762,10 @@ func usefield(n *ir.Node) { } sym := tracksym(outer, field) - if Curfn.Func.FieldTrack == nil { - Curfn.Func.FieldTrack = make(map[*types.Sym]struct{}) + if Curfn.Func().FieldTrack == nil { + Curfn.Func().FieldTrack = make(map[*types.Sym]struct{}) } - Curfn.Func.FieldTrack[sym] = struct{}{} + Curfn.Func().FieldTrack[sym] = struct{}{} } func candiscardlist(l ir.Nodes) bool { @@ -3782,7 +3782,7 @@ func candiscard(n *ir.Node) bool { return true } - switch n.Op { + switch n.Op() { default: return false @@ -3844,14 +3844,14 @@ func candiscard(n *ir.Node) bool { // Discardable as long as we know it's not division by zero. case ir.ODIV, ir.OMOD: - if n.Right.Op == ir.OLITERAL && constant.Sign(n.Right.Val()) != 0 { + if n.Right().Op() == ir.OLITERAL && constant.Sign(n.Right().Val()) != 0 { break } return false // Discardable as long as we know it won't fail because of a bad size. case ir.OMAKECHAN, ir.OMAKEMAP: - if ir.IsConst(n.Left, constant.Int) && constant.Sign(n.Left.Val()) == 0 { + if ir.IsConst(n.Left(), constant.Int) && constant.Sign(n.Left().Val()) == 0 { break } return false @@ -3864,7 +3864,7 @@ func candiscard(n *ir.Node) bool { return false } - if !candiscard(n.Left) || !candiscard(n.Right) || !candiscardlist(n.Ninit) || !candiscardlist(n.Nbody) || !candiscardlist(n.List) || !candiscardlist(n.Rlist) { + if !candiscard(n.Left()) || !candiscard(n.Right()) || !candiscardlist(n.Init()) || !candiscardlist(n.Body()) || !candiscardlist(n.List()) || !candiscardlist(n.Rlist()) { return false } @@ -3892,66 +3892,66 @@ var wrapCall_prgen int // The result of wrapCall MUST be assigned back to n, e.g. // n.Left = wrapCall(n.Left, init) func wrapCall(n *ir.Node, init *ir.Nodes) *ir.Node { - if n.Ninit.Len() != 0 { - walkstmtlist(n.Ninit.Slice()) - init.AppendNodes(&n.Ninit) + if n.Init().Len() != 0 { + walkstmtlist(n.Init().Slice()) + init.AppendNodes(n.PtrInit()) } - isBuiltinCall := n.Op != ir.OCALLFUNC && n.Op != ir.OCALLMETH && n.Op != ir.OCALLINTER + isBuiltinCall := n.Op() != ir.OCALLFUNC && n.Op() != ir.OCALLMETH && n.Op() != ir.OCALLINTER // Turn f(a, b, []T{c, d, e}...) back into f(a, b, c, d, e). if !isBuiltinCall && n.IsDDD() { - last := n.List.Len() - 1 - if va := n.List.Index(last); va.Op == ir.OSLICELIT { - n.List.Set(append(n.List.Slice()[:last], va.List.Slice()...)) + last := n.List().Len() - 1 + if va := n.List().Index(last); va.Op() == ir.OSLICELIT { + n.PtrList().Set(append(n.List().Slice()[:last], va.List().Slice()...)) n.SetIsDDD(false) } } // origArgs keeps track of what argument is uintptr-unsafe/unsafe-uintptr conversion. - origArgs := make([]*ir.Node, n.List.Len()) + origArgs := make([]*ir.Node, n.List().Len()) t := ir.Nod(ir.OTFUNC, nil, nil) - for i, arg := range n.List.Slice() { + for i, arg := range n.List().Slice() { s := lookupN("a", i) - if !isBuiltinCall && arg.Op == ir.OCONVNOP && arg.Type.IsUintptr() && arg.Left.Type.IsUnsafePtr() { + if !isBuiltinCall && arg.Op() == ir.OCONVNOP && arg.Type().IsUintptr() && arg.Left().Type().IsUnsafePtr() { origArgs[i] = arg - arg = arg.Left - n.List.SetIndex(i, arg) + arg = arg.Left() + n.List().SetIndex(i, arg) } - t.List.Append(symfield(s, arg.Type)) + t.PtrList().Append(symfield(s, arg.Type())) } wrapCall_prgen++ sym := lookupN("wrap·", wrapCall_prgen) fn := dclfunc(sym, t) - args := paramNnames(t.Type) + args := paramNnames(t.Type()) for i, origArg := range origArgs { if origArg == nil { continue } - arg := ir.Nod(origArg.Op, args[i], nil) - arg.Type = origArg.Type + arg := ir.Nod(origArg.Op(), args[i], nil) + arg.SetType(origArg.Type()) args[i] = arg } - call := ir.Nod(n.Op, nil, nil) + call := ir.Nod(n.Op(), nil, nil) if !isBuiltinCall { - call.Op = ir.OCALL - call.Left = n.Left + call.SetOp(ir.OCALL) + call.SetLeft(n.Left()) call.SetIsDDD(n.IsDDD()) } - call.List.Set(args) - fn.Nbody.Set1(call) + call.PtrList().Set(args) + fn.PtrBody().Set1(call) funcbody() fn = typecheck(fn, ctxStmt) - typecheckslice(fn.Nbody.Slice(), ctxStmt) + typecheckslice(fn.Body().Slice(), ctxStmt) xtop = append(xtop, fn) call = ir.Nod(ir.OCALL, nil, nil) - call.Left = fn.Func.Nname - call.List.Set(n.List.Slice()) + call.SetLeft(fn.Func().Nname) + call.PtrList().Set(n.List().Slice()) call = typecheck(call, ctxStmt) call = walkexpr(call, init) return call @@ -3968,7 +3968,7 @@ func substArgTypes(old *ir.Node, types_ ...*types.Type) *ir.Node { for _, t := range types_ { dowidth(t) } - n.Type = types.SubstAny(n.Type, &types_) + n.SetType(types.SubstAny(n.Type(), &types_)) if len(types_) > 0 { base.Fatalf("substArgTypes: too many argument types") } @@ -3993,14 +3993,14 @@ func canMergeLoads() bool { // isRuneCount reports whether n is of the form len([]rune(string)). // These are optimized into a call to runtime.countrunes. func isRuneCount(n *ir.Node) bool { - return base.Flag.N == 0 && !instrumenting && n.Op == ir.OLEN && n.Left.Op == ir.OSTR2RUNES + return base.Flag.N == 0 && !instrumenting && n.Op() == ir.OLEN && n.Left().Op() == ir.OSTR2RUNES } func walkCheckPtrAlignment(n *ir.Node, init *ir.Nodes, count *ir.Node) *ir.Node { - if !n.Type.IsPtr() { - base.Fatalf("expected pointer type: %v", n.Type) + if !n.Type().IsPtr() { + base.Fatalf("expected pointer type: %v", n.Type()) } - elem := n.Type.Elem() + elem := n.Type().Elem() if count != nil { if !elem.IsArray() { base.Fatalf("expected array type: %v", elem) @@ -4017,8 +4017,8 @@ func walkCheckPtrAlignment(n *ir.Node, init *ir.Nodes, count *ir.Node) *ir.Node count = nodintconst(1) } - n.Left = cheapexpr(n.Left, init) - init.Append(mkcall("checkptrAlignment", nil, init, convnop(n.Left, types.Types[types.TUNSAFEPTR]), typename(elem), conv(count, types.Types[types.TUINTPTR]))) + n.SetLeft(cheapexpr(n.Left(), init)) + init.Append(mkcall("checkptrAlignment", nil, init, convnop(n.Left(), types.Types[types.TUNSAFEPTR]), typename(elem), conv(count, types.Types[types.TUINTPTR]))) return n } @@ -4040,12 +4040,12 @@ func walkCheckPtrArithmetic(n *ir.Node, init *ir.Nodes) *ir.Node { // TODO(mdempsky): Make stricter. We only need to exempt // reflect.Value.Pointer and reflect.Value.UnsafeAddr. - switch n.Left.Op { + switch n.Left().Op() { case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER: return n } - if n.Left.Op == ir.ODOTPTR && isReflectHeaderDataField(n.Left) { + if n.Left().Op() == ir.ODOTPTR && isReflectHeaderDataField(n.Left()) { return n } @@ -4058,25 +4058,25 @@ func walkCheckPtrArithmetic(n *ir.Node, init *ir.Nodes) *ir.Node { var originals []*ir.Node var walk func(n *ir.Node) walk = func(n *ir.Node) { - switch n.Op { + switch n.Op() { case ir.OADD: - walk(n.Left) - walk(n.Right) + walk(n.Left()) + walk(n.Right()) case ir.OSUB, ir.OANDNOT: - walk(n.Left) + walk(n.Left()) case ir.OCONVNOP: - if n.Left.Type.IsUnsafePtr() { - n.Left = cheapexpr(n.Left, init) - originals = append(originals, convnop(n.Left, types.Types[types.TUNSAFEPTR])) + if n.Left().Type().IsUnsafePtr() { + n.SetLeft(cheapexpr(n.Left(), init)) + originals = append(originals, convnop(n.Left(), types.Types[types.TUNSAFEPTR])) } } } - walk(n.Left) + walk(n.Left()) n = cheapexpr(n, init) slice := mkdotargslice(types.NewSlice(types.Types[types.TUNSAFEPTR]), originals) - slice.Esc = EscNone + slice.SetEsc(EscNone) init.Append(mkcall("checkptrArithmetic", nil, init, convnop(n, types.Types[types.TUNSAFEPTR]), slice)) // TODO(khr): Mark backing store of slice as dead. This will allow us to reuse @@ -4089,5 +4089,5 @@ func walkCheckPtrArithmetic(n *ir.Node, init *ir.Nodes) *ir.Node { // function fn at a given level. See debugHelpFooter for defined // levels. func checkPtr(fn *ir.Node, level int) bool { - return base.Debug.Checkptr >= level && fn.Func.Pragma&ir.NoCheckPtr == 0 + return base.Debug.Checkptr >= level && fn.Func().Pragma&ir.NoCheckPtr == 0 } diff --git a/src/cmd/compile/internal/ir/dump.go b/src/cmd/compile/internal/ir/dump.go index 9306366e8a..43d0742c73 100644 --- a/src/cmd/compile/internal/ir/dump.go +++ b/src/cmd/compile/internal/ir/dump.go @@ -205,7 +205,7 @@ func (p *dumper) dump(x reflect.Value, depth int) { isNode := false if n, ok := x.Interface().(Node); ok { isNode = true - p.printf("%s %s {", n.Op.String(), p.addr(x)) + p.printf("%s %s {", n.op.String(), p.addr(x)) } else { p.printf("%s {", typ) } diff --git a/src/cmd/compile/internal/ir/fmt.go b/src/cmd/compile/internal/ir/fmt.go index 5dea0880fc..e1e3813368 100644 --- a/src/cmd/compile/internal/ir/fmt.go +++ b/src/cmd/compile/internal/ir/fmt.go @@ -351,28 +351,28 @@ func jconvFmt(n *Node, s fmt.State, flag FmtFlag) { if base.Debug.DumpPtrs != 0 { fmt.Fprintf(s, " p(%p)", n) } - if !short && n.Name != nil && n.Name.Vargen != 0 { - fmt.Fprintf(s, " g(%d)", n.Name.Vargen) + if !short && n.Name() != nil && n.Name().Vargen != 0 { + fmt.Fprintf(s, " g(%d)", n.Name().Vargen) } - if base.Debug.DumpPtrs != 0 && !short && n.Name != nil && n.Name.Defn != nil { + if base.Debug.DumpPtrs != 0 && !short && n.Name() != nil && n.Name().Defn != nil { // Useful to see where Defn is set and what node it points to - fmt.Fprintf(s, " defn(%p)", n.Name.Defn) + fmt.Fprintf(s, " defn(%p)", n.Name().Defn) } - if n.Pos.IsKnown() { + if n.Pos().IsKnown() { pfx := "" - switch n.Pos.IsStmt() { + switch n.Pos().IsStmt() { case src.PosNotStmt: pfx = "_" // "-" would be confusing case src.PosIsStmt: pfx = "+" } - fmt.Fprintf(s, " l(%s%d)", pfx, n.Pos.Line()) + fmt.Fprintf(s, " l(%s%d)", pfx, n.Pos().Line()) } - if !short && n.Xoffset != types.BADWIDTH { - fmt.Fprintf(s, " x(%d)", n.Xoffset) + if !short && n.Offset() != types.BADWIDTH { + fmt.Fprintf(s, " x(%d)", n.Offset()) } if n.Class() != 0 { @@ -405,20 +405,20 @@ func jconvFmt(n *Node, s fmt.State, flag FmtFlag) { fmt.Fprintf(s, " embedded") } - if n.Op == ONAME { - if n.Name.Addrtaken() { + if n.Op() == ONAME { + if n.Name().Addrtaken() { fmt.Fprint(s, " addrtaken") } - if n.Name.Assigned() { + if n.Name().Assigned() { fmt.Fprint(s, " assigned") } - if n.Name.IsClosureVar() { + if n.Name().IsClosureVar() { fmt.Fprint(s, " closurevar") } - if n.Name.Captured() { + if n.Name().Captured() { fmt.Fprint(s, " captured") } - if n.Name.IsOutputParamHeapAddr() { + if n.Name().IsOutputParamHeapAddr() { fmt.Fprint(s, " outputparamheapaddr") } } @@ -433,7 +433,7 @@ func jconvFmt(n *Node, s fmt.State, flag FmtFlag) { fmt.Fprint(s, " hascall") } - if !short && n.Name != nil && n.Name.Used() { + if !short && n.Name() != nil && n.Name().Used() { fmt.Fprint(s, " used") } } @@ -899,31 +899,31 @@ func stmtFmt(n *Node, s fmt.State, mode FmtMode) { // block starting with the init statements. // if we can just say "for" n->ninit; ... then do so - simpleinit := n.Ninit.Len() == 1 && n.Ninit.First().Ninit.Len() == 0 && StmtWithInit(n.Op) + simpleinit := n.Init().Len() == 1 && n.Init().First().Init().Len() == 0 && StmtWithInit(n.Op()) // otherwise, print the inits as separate statements - complexinit := n.Ninit.Len() != 0 && !simpleinit && (mode != FErr) + complexinit := n.Init().Len() != 0 && !simpleinit && (mode != FErr) // but if it was for if/for/switch, put in an extra surrounding block to limit the scope - extrablock := complexinit && StmtWithInit(n.Op) + extrablock := complexinit && StmtWithInit(n.Op()) if extrablock { fmt.Fprint(s, "{") } if complexinit { - mode.Fprintf(s, " %v; ", n.Ninit) + mode.Fprintf(s, " %v; ", n.Init()) } - switch n.Op { + switch n.Op() { case ODCL: - mode.Fprintf(s, "var %v %v", n.Left.Sym, n.Left.Type) + mode.Fprintf(s, "var %v %v", n.Left().Sym(), n.Left().Type()) case ODCLFIELD: - if n.Sym != nil { - mode.Fprintf(s, "%v %v", n.Sym, n.Left) + if n.Sym() != nil { + mode.Fprintf(s, "%v %v", n.Sym(), n.Left()) } else { - mode.Fprintf(s, "%v", n.Left) + mode.Fprintf(s, "%v", n.Left()) } // Don't export "v = " initializing statements, hope they're always @@ -931,61 +931,61 @@ func stmtFmt(n *Node, s fmt.State, mode FmtMode) { // the "v = " again. case OAS: if n.Colas() && !complexinit { - mode.Fprintf(s, "%v := %v", n.Left, n.Right) + mode.Fprintf(s, "%v := %v", n.Left(), n.Right()) } else { - mode.Fprintf(s, "%v = %v", n.Left, n.Right) + mode.Fprintf(s, "%v = %v", n.Left(), n.Right()) } case OASOP: if n.Implicit() { if n.SubOp() == OADD { - mode.Fprintf(s, "%v++", n.Left) + mode.Fprintf(s, "%v++", n.Left()) } else { - mode.Fprintf(s, "%v--", n.Left) + mode.Fprintf(s, "%v--", n.Left()) } break } - mode.Fprintf(s, "%v %#v= %v", n.Left, n.SubOp(), n.Right) + mode.Fprintf(s, "%v %#v= %v", n.Left(), n.SubOp(), n.Right()) case OAS2: if n.Colas() && !complexinit { - mode.Fprintf(s, "%.v := %.v", n.List, n.Rlist) + mode.Fprintf(s, "%.v := %.v", n.List(), n.Rlist()) break } fallthrough case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV: - mode.Fprintf(s, "%.v = %v", n.List, n.Right) + mode.Fprintf(s, "%.v = %v", n.List(), n.Right()) case ORETURN: - mode.Fprintf(s, "return %.v", n.List) + mode.Fprintf(s, "return %.v", n.List()) case ORETJMP: - mode.Fprintf(s, "retjmp %v", n.Sym) + mode.Fprintf(s, "retjmp %v", n.Sym()) case OINLMARK: - mode.Fprintf(s, "inlmark %d", n.Xoffset) + mode.Fprintf(s, "inlmark %d", n.Offset()) case OGO: - mode.Fprintf(s, "go %v", n.Left) + mode.Fprintf(s, "go %v", n.Left()) case ODEFER: - mode.Fprintf(s, "defer %v", n.Left) + mode.Fprintf(s, "defer %v", n.Left()) case OIF: if simpleinit { - mode.Fprintf(s, "if %v; %v { %v }", n.Ninit.First(), n.Left, n.Nbody) + mode.Fprintf(s, "if %v; %v { %v }", n.Init().First(), n.Left(), n.Body()) } else { - mode.Fprintf(s, "if %v { %v }", n.Left, n.Nbody) + mode.Fprintf(s, "if %v { %v }", n.Left(), n.Body()) } - if n.Rlist.Len() != 0 { - mode.Fprintf(s, " else { %v }", n.Rlist) + if n.Rlist().Len() != 0 { + mode.Fprintf(s, " else { %v }", n.Rlist()) } case OFOR, OFORUNTIL: opname := "for" - if n.Op == OFORUNTIL { + if n.Op() == OFORUNTIL { opname = "foruntil" } if mode == FErr { // TODO maybe only if FmtShort, same below @@ -995,26 +995,26 @@ func stmtFmt(n *Node, s fmt.State, mode FmtMode) { fmt.Fprint(s, opname) if simpleinit { - mode.Fprintf(s, " %v;", n.Ninit.First()) - } else if n.Right != nil { + mode.Fprintf(s, " %v;", n.Init().First()) + } else if n.Right() != nil { fmt.Fprint(s, " ;") } - if n.Left != nil { - mode.Fprintf(s, " %v", n.Left) + if n.Left() != nil { + mode.Fprintf(s, " %v", n.Left()) } - if n.Right != nil { - mode.Fprintf(s, "; %v", n.Right) + if n.Right() != nil { + mode.Fprintf(s, "; %v", n.Right()) } else if simpleinit { fmt.Fprint(s, ";") } - if n.Op == OFORUNTIL && n.List.Len() != 0 { - mode.Fprintf(s, "; %v", n.List) + if n.Op() == OFORUNTIL && n.List().Len() != 0 { + mode.Fprintf(s, "; %v", n.List()) } - mode.Fprintf(s, " { %v }", n.Nbody) + mode.Fprintf(s, " { %v }", n.Body()) case ORANGE: if mode == FErr { @@ -1022,49 +1022,49 @@ func stmtFmt(n *Node, s fmt.State, mode FmtMode) { break } - if n.List.Len() == 0 { - mode.Fprintf(s, "for range %v { %v }", n.Right, n.Nbody) + if n.List().Len() == 0 { + mode.Fprintf(s, "for range %v { %v }", n.Right(), n.Body()) break } - mode.Fprintf(s, "for %.v = range %v { %v }", n.List, n.Right, n.Nbody) + mode.Fprintf(s, "for %.v = range %v { %v }", n.List(), n.Right(), n.Body()) case OSELECT, OSWITCH: if mode == FErr { - mode.Fprintf(s, "%v statement", n.Op) + mode.Fprintf(s, "%v statement", n.Op()) break } - mode.Fprintf(s, "%#v", n.Op) + mode.Fprintf(s, "%#v", n.Op()) if simpleinit { - mode.Fprintf(s, " %v;", n.Ninit.First()) + mode.Fprintf(s, " %v;", n.Init().First()) } - if n.Left != nil { - mode.Fprintf(s, " %v ", n.Left) + if n.Left() != nil { + mode.Fprintf(s, " %v ", n.Left()) } - mode.Fprintf(s, " { %v }", n.List) + mode.Fprintf(s, " { %v }", n.List()) case OCASE: - if n.List.Len() != 0 { - mode.Fprintf(s, "case %.v", n.List) + if n.List().Len() != 0 { + mode.Fprintf(s, "case %.v", n.List()) } else { fmt.Fprint(s, "default") } - mode.Fprintf(s, ": %v", n.Nbody) + mode.Fprintf(s, ": %v", n.Body()) case OBREAK, OCONTINUE, OGOTO, OFALL: - if n.Sym != nil { - mode.Fprintf(s, "%#v %v", n.Op, n.Sym) + if n.Sym() != nil { + mode.Fprintf(s, "%#v %v", n.Op(), n.Sym()) } else { - mode.Fprintf(s, "%#v", n.Op) + mode.Fprintf(s, "%#v", n.Op()) } case OEMPTY: break case OLABEL: - mode.Fprintf(s, "%v: ", n.Sym) + mode.Fprintf(s, "%v: ", n.Sym()) } if extrablock { @@ -1193,8 +1193,8 @@ var OpPrec = []int{ } func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) { - for n != nil && n.Implicit() && (n.Op == ODEREF || n.Op == OADDR) { - n = n.Left + for n != nil && n.Implicit() && (n.Op() == ODEREF || n.Op() == OADDR) { + n = n.Left() } if n == nil { @@ -1202,8 +1202,8 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) { return } - nprec := OpPrec[n.Op] - if n.Op == OTYPE && n.Sym != nil { + nprec := OpPrec[n.Op()] + if n.Op() == OTYPE && n.Sym() != nil { nprec = 8 } @@ -1212,38 +1212,38 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) { return } - switch n.Op { + switch n.Op() { case OPAREN: - mode.Fprintf(s, "(%v)", n.Left) + mode.Fprintf(s, "(%v)", n.Left()) case ONIL: fmt.Fprint(s, "nil") case OLITERAL: // this is a bit of a mess if mode == FErr { - if n.Orig != nil && n.Orig != n { - exprFmt(n.Orig, s, prec, mode) + if n.Orig() != nil && n.Orig() != n { + exprFmt(n.Orig(), s, prec, mode) return } - if n.Sym != nil { - fmt.Fprint(s, smodeString(n.Sym, mode)) + if n.Sym() != nil { + fmt.Fprint(s, smodeString(n.Sym(), mode)) return } } needUnparen := false - if n.Type != nil && !n.Type.IsUntyped() { + if n.Type() != nil && !n.Type().IsUntyped() { // Need parens when type begins with what might // be misinterpreted as a unary operator: * or <-. - if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == types.Crecv) { - mode.Fprintf(s, "(%v)(", n.Type) + if n.Type().IsPtr() || (n.Type().IsChan() && n.Type().ChanDir() == types.Crecv) { + mode.Fprintf(s, "(%v)(", n.Type()) } else { - mode.Fprintf(s, "%v(", n.Type) + mode.Fprintf(s, "%v(", n.Type()) } needUnparen = true } - if n.Type == types.UntypedRune { + if n.Type() == types.UntypedRune { switch x, ok := constant.Int64Val(n.Val()); { case !ok: fallthrough @@ -1270,44 +1270,44 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) { case ONAME: // Special case: name used as local variable in export. // _ becomes ~b%d internally; print as _ for export - if mode == FErr && n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' { + if mode == FErr && n.Sym() != nil && n.Sym().Name[0] == '~' && n.Sym().Name[1] == 'b' { fmt.Fprint(s, "_") return } fallthrough case OPACK, ONONAME, OMETHEXPR: - fmt.Fprint(s, smodeString(n.Sym, mode)) + fmt.Fprint(s, smodeString(n.Sym(), mode)) case OTYPE: - if n.Type == nil && n.Sym != nil { - fmt.Fprint(s, smodeString(n.Sym, mode)) + if n.Type() == nil && n.Sym() != nil { + fmt.Fprint(s, smodeString(n.Sym(), mode)) return } - mode.Fprintf(s, "%v", n.Type) + mode.Fprintf(s, "%v", n.Type()) case OTARRAY: - if n.Left != nil { - mode.Fprintf(s, "[%v]%v", n.Left, n.Right) + if n.Left() != nil { + mode.Fprintf(s, "[%v]%v", n.Left(), n.Right()) return } - mode.Fprintf(s, "[]%v", n.Right) // happens before typecheck + mode.Fprintf(s, "[]%v", n.Right()) // happens before typecheck case OTMAP: - mode.Fprintf(s, "map[%v]%v", n.Left, n.Right) + mode.Fprintf(s, "map[%v]%v", n.Left(), n.Right()) case OTCHAN: switch n.TChanDir() { case types.Crecv: - mode.Fprintf(s, "<-chan %v", n.Left) + mode.Fprintf(s, "<-chan %v", n.Left()) case types.Csend: - mode.Fprintf(s, "chan<- %v", n.Left) + mode.Fprintf(s, "chan<- %v", n.Left()) default: - if n.Left != nil && n.Left.Op == OTCHAN && n.Left.Sym == nil && n.Left.TChanDir() == types.Crecv { - mode.Fprintf(s, "chan (%v)", n.Left) + if n.Left() != nil && n.Left().Op() == OTCHAN && n.Left().Sym() == nil && n.Left().TChanDir() == types.Crecv { + mode.Fprintf(s, "chan (%v)", n.Left()) } else { - mode.Fprintf(s, "chan %v", n.Left) + mode.Fprintf(s, "chan %v", n.Left()) } } @@ -1325,11 +1325,11 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) { fmt.Fprint(s, "func literal") return } - if n.Nbody.Len() != 0 { - mode.Fprintf(s, "%v { %v }", n.Type, n.Nbody) + if n.Body().Len() != 0 { + mode.Fprintf(s, "%v { %v }", n.Type(), n.Body()) return } - mode.Fprintf(s, "%v { %v }", n.Type, n.Func.Decl.Nbody) + mode.Fprintf(s, "%v { %v }", n.Type(), n.Func().Decl.Body()) case OCOMPLIT: if mode == FErr { @@ -1337,75 +1337,75 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) { mode.Fprintf(s, "... argument") return } - if n.Right != nil { - mode.Fprintf(s, "%v{%s}", n.Right, ellipsisIf(n.List.Len() != 0)) + if n.Right() != nil { + mode.Fprintf(s, "%v{%s}", n.Right(), ellipsisIf(n.List().Len() != 0)) return } fmt.Fprint(s, "composite literal") return } - mode.Fprintf(s, "(%v{ %.v })", n.Right, n.List) + mode.Fprintf(s, "(%v{ %.v })", n.Right(), n.List()) case OPTRLIT: - mode.Fprintf(s, "&%v", n.Left) + mode.Fprintf(s, "&%v", n.Left()) case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT: if mode == FErr { - mode.Fprintf(s, "%v{%s}", n.Type, ellipsisIf(n.List.Len() != 0)) + mode.Fprintf(s, "%v{%s}", n.Type(), ellipsisIf(n.List().Len() != 0)) return } - mode.Fprintf(s, "(%v{ %.v })", n.Type, n.List) + mode.Fprintf(s, "(%v{ %.v })", n.Type(), n.List()) case OKEY: - if n.Left != nil && n.Right != nil { - mode.Fprintf(s, "%v:%v", n.Left, n.Right) + if n.Left() != nil && n.Right() != nil { + mode.Fprintf(s, "%v:%v", n.Left(), n.Right()) return } - if n.Left == nil && n.Right != nil { - mode.Fprintf(s, ":%v", n.Right) + if n.Left() == nil && n.Right() != nil { + mode.Fprintf(s, ":%v", n.Right()) return } - if n.Left != nil && n.Right == nil { - mode.Fprintf(s, "%v:", n.Left) + if n.Left() != nil && n.Right() == nil { + mode.Fprintf(s, "%v:", n.Left()) return } fmt.Fprint(s, ":") case OSTRUCTKEY: - mode.Fprintf(s, "%v:%v", n.Sym, n.Left) + mode.Fprintf(s, "%v:%v", n.Sym(), n.Left()) case OCALLPART: - exprFmt(n.Left, s, nprec, mode) - if n.Right == nil || n.Right.Sym == nil { + exprFmt(n.Left(), s, nprec, mode) + if n.Right() == nil || n.Right().Sym() == nil { fmt.Fprint(s, ".") return } - mode.Fprintf(s, ".%0S", n.Right.Sym) + mode.Fprintf(s, ".%0S", n.Right().Sym()) case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH: - exprFmt(n.Left, s, nprec, mode) - if n.Sym == nil { + exprFmt(n.Left(), s, nprec, mode) + if n.Sym() == nil { fmt.Fprint(s, ".") return } - mode.Fprintf(s, ".%0S", n.Sym) + mode.Fprintf(s, ".%0S", n.Sym()) case ODOTTYPE, ODOTTYPE2: - exprFmt(n.Left, s, nprec, mode) - if n.Right != nil { - mode.Fprintf(s, ".(%v)", n.Right) + exprFmt(n.Left(), s, nprec, mode) + if n.Right() != nil { + mode.Fprintf(s, ".(%v)", n.Right()) return } - mode.Fprintf(s, ".(%v)", n.Type) + mode.Fprintf(s, ".(%v)", n.Type()) case OINDEX, OINDEXMAP: - exprFmt(n.Left, s, nprec, mode) - mode.Fprintf(s, "[%v]", n.Right) + exprFmt(n.Left(), s, nprec, mode) + mode.Fprintf(s, "[%v]", n.Right()) case OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR: - exprFmt(n.Left, s, nprec, mode) + exprFmt(n.Left(), s, nprec, mode) fmt.Fprint(s, "[") low, high, max := n.SliceBounds() if low != nil { @@ -1415,7 +1415,7 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) { if high != nil { fmt.Fprint(s, modeString(high, mode)) } - if n.Op.IsSlice3() { + if n.Op().IsSlice3() { fmt.Fprint(s, ":") if max != nil { fmt.Fprint(s, modeString(max, mode)) @@ -1424,16 +1424,16 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) { fmt.Fprint(s, "]") case OSLICEHEADER: - if n.List.Len() != 2 { - base.Fatalf("bad OSLICEHEADER list length %d", n.List.Len()) + if n.List().Len() != 2 { + base.Fatalf("bad OSLICEHEADER list length %d", n.List().Len()) } - mode.Fprintf(s, "sliceheader{%v,%v,%v}", n.Left, n.List.First(), n.List.Second()) + mode.Fprintf(s, "sliceheader{%v,%v,%v}", n.Left(), n.List().First(), n.List().Second()) case OCOMPLEX, OCOPY: - if n.Left != nil { - mode.Fprintf(s, "%#v(%v, %v)", n.Op, n.Left, n.Right) + if n.Left() != nil { + mode.Fprintf(s, "%#v(%v, %v)", n.Op(), n.Left(), n.Right()) } else { - mode.Fprintf(s, "%#v(%.v)", n.Op, n.List) + mode.Fprintf(s, "%#v(%.v)", n.Op(), n.List()) } case OCONV, @@ -1444,15 +1444,15 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) { OSTR2BYTES, OSTR2RUNES, ORUNESTR: - if n.Type == nil || n.Type.Sym == nil { - mode.Fprintf(s, "(%v)", n.Type) + if n.Type() == nil || n.Type().Sym == nil { + mode.Fprintf(s, "(%v)", n.Type()) } else { - mode.Fprintf(s, "%v", n.Type) + mode.Fprintf(s, "%v", n.Type()) } - if n.Left != nil { - mode.Fprintf(s, "(%v)", n.Left) + if n.Left() != nil { + mode.Fprintf(s, "(%v)", n.Left()) } else { - mode.Fprintf(s, "(%.v)", n.List) + mode.Fprintf(s, "(%.v)", n.List()) } case OREAL, @@ -1471,49 +1471,49 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) { OSIZEOF, OPRINT, OPRINTN: - if n.Left != nil { - mode.Fprintf(s, "%#v(%v)", n.Op, n.Left) + if n.Left() != nil { + mode.Fprintf(s, "%#v(%v)", n.Op(), n.Left()) return } if n.IsDDD() { - mode.Fprintf(s, "%#v(%.v...)", n.Op, n.List) + mode.Fprintf(s, "%#v(%.v...)", n.Op(), n.List()) return } - mode.Fprintf(s, "%#v(%.v)", n.Op, n.List) + mode.Fprintf(s, "%#v(%.v)", n.Op(), n.List()) case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG: - exprFmt(n.Left, s, nprec, mode) + exprFmt(n.Left(), s, nprec, mode) if n.IsDDD() { - mode.Fprintf(s, "(%.v...)", n.List) + mode.Fprintf(s, "(%.v...)", n.List()) return } - mode.Fprintf(s, "(%.v)", n.List) + mode.Fprintf(s, "(%.v)", n.List()) case OMAKEMAP, OMAKECHAN, OMAKESLICE: - if n.List.Len() != 0 { // pre-typecheck - mode.Fprintf(s, "make(%v, %.v)", n.Type, n.List) + if n.List().Len() != 0 { // pre-typecheck + mode.Fprintf(s, "make(%v, %.v)", n.Type(), n.List()) return } - if n.Right != nil { - mode.Fprintf(s, "make(%v, %v, %v)", n.Type, n.Left, n.Right) + if n.Right() != nil { + mode.Fprintf(s, "make(%v, %v, %v)", n.Type(), n.Left(), n.Right()) return } - if n.Left != nil && (n.Op == OMAKESLICE || !n.Left.Type.IsUntyped()) { - mode.Fprintf(s, "make(%v, %v)", n.Type, n.Left) + if n.Left() != nil && (n.Op() == OMAKESLICE || !n.Left().Type().IsUntyped()) { + mode.Fprintf(s, "make(%v, %v)", n.Type(), n.Left()) return } - mode.Fprintf(s, "make(%v)", n.Type) + mode.Fprintf(s, "make(%v)", n.Type()) case OMAKESLICECOPY: - mode.Fprintf(s, "makeslicecopy(%v, %v, %v)", n.Type, n.Left, n.Right) + mode.Fprintf(s, "makeslicecopy(%v, %v, %v)", n.Type(), n.Left(), n.Right()) case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV: // Unary - mode.Fprintf(s, "%#v", n.Op) - if n.Left != nil && n.Left.Op == n.Op { + mode.Fprintf(s, "%#v", n.Op()) + if n.Left() != nil && n.Left().Op() == n.Op() { fmt.Fprint(s, " ") } - exprFmt(n.Left, s, nprec+1, mode) + exprFmt(n.Left(), s, nprec+1, mode) // Binary case OADD, @@ -1536,12 +1536,12 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) { OSEND, OSUB, OXOR: - exprFmt(n.Left, s, nprec, mode) - mode.Fprintf(s, " %#v ", n.Op) - exprFmt(n.Right, s, nprec+1, mode) + exprFmt(n.Left(), s, nprec, mode) + mode.Fprintf(s, " %#v ", n.Op()) + exprFmt(n.Right(), s, nprec+1, mode) case OADDSTR: - for i, n1 := range n.List.Slice() { + for i, n1 := range n.List().Slice() { if i != 0 { fmt.Fprint(s, " + ") } @@ -1550,23 +1550,23 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) { case ODDD: mode.Fprintf(s, "...") default: - mode.Fprintf(s, "", n.Op) + mode.Fprintf(s, "", n.Op()) } } func nodeFmt(n *Node, s fmt.State, flag FmtFlag, mode FmtMode) { - t := n.Type + t := n.Type() // We almost always want the original. // TODO(gri) Why the special case for OLITERAL? - if n.Op != OLITERAL && n.Orig != nil { - n = n.Orig + if n.Op() != OLITERAL && n.Orig() != nil { + n = n.Orig() } if flag&FmtLong != 0 && t != nil { if t.Etype == types.TNIL { fmt.Fprint(s, "nil") - } else if n.Op == ONAME && n.Name.AutoTemp() { + } else if n.Op() == ONAME && n.Name().AutoTemp() { mode.Fprintf(s, "%v value", t) } else { mode.Fprintf(s, "%v (type %v)", n, t) @@ -1576,7 +1576,7 @@ func nodeFmt(n *Node, s fmt.State, flag FmtFlag, mode FmtMode) { // TODO inlining produces expressions with ninits. we can't print these yet. - if OpPrec[n.Op] < 0 { + if OpPrec[n.Op()] < 0 { stmtFmt(n, s, mode) return } @@ -1594,82 +1594,82 @@ func nodeDumpFmt(n *Node, s fmt.State, flag FmtFlag, mode FmtMode) { return } - if n.Ninit.Len() != 0 { - mode.Fprintf(s, "%v-init%v", n.Op, n.Ninit) + if n.Init().Len() != 0 { + mode.Fprintf(s, "%v-init%v", n.Op(), n.Init()) indent(s) } } - switch n.Op { + switch n.Op() { default: - mode.Fprintf(s, "%v%j", n.Op, n) + mode.Fprintf(s, "%v%j", n.Op(), n) case OLITERAL: - mode.Fprintf(s, "%v-%v%j", n.Op, n.Val(), n) + mode.Fprintf(s, "%v-%v%j", n.Op(), n.Val(), n) case ONAME, ONONAME, OMETHEXPR: - if n.Sym != nil { - mode.Fprintf(s, "%v-%v%j", n.Op, n.Sym, n) + if n.Sym() != nil { + mode.Fprintf(s, "%v-%v%j", n.Op(), n.Sym(), n) } else { - mode.Fprintf(s, "%v%j", n.Op, n) + mode.Fprintf(s, "%v%j", n.Op(), n) } - if recur && n.Type == nil && n.Name != nil && n.Name.Param != nil && n.Name.Param.Ntype != nil { + if recur && n.Type() == nil && n.Name() != nil && n.Name().Param != nil && n.Name().Param.Ntype != nil { indent(s) - mode.Fprintf(s, "%v-ntype%v", n.Op, n.Name.Param.Ntype) + mode.Fprintf(s, "%v-ntype%v", n.Op(), n.Name().Param.Ntype) } case OASOP: - mode.Fprintf(s, "%v-%v%j", n.Op, n.SubOp(), n) + mode.Fprintf(s, "%v-%v%j", n.Op(), n.SubOp(), n) case OTYPE: - mode.Fprintf(s, "%v %v%j type=%v", n.Op, n.Sym, n, n.Type) - if recur && n.Type == nil && n.Name != nil && n.Name.Param != nil && n.Name.Param.Ntype != nil { + mode.Fprintf(s, "%v %v%j type=%v", n.Op(), n.Sym(), n, n.Type()) + if recur && n.Type() == nil && n.Name() != nil && n.Name().Param != nil && n.Name().Param.Ntype != nil { indent(s) - mode.Fprintf(s, "%v-ntype%v", n.Op, n.Name.Param.Ntype) + mode.Fprintf(s, "%v-ntype%v", n.Op(), n.Name().Param.Ntype) } } - if n.Op == OCLOSURE && n.Func.Decl != nil && n.Func.Nname.Sym != nil { - mode.Fprintf(s, " fnName %v", n.Func.Nname.Sym) + if n.Op() == OCLOSURE && n.Func().Decl != nil && n.Func().Nname.Sym() != nil { + mode.Fprintf(s, " fnName %v", n.Func().Nname.Sym()) } - if n.Sym != nil && n.Op != ONAME { - mode.Fprintf(s, " %v", n.Sym) + if n.Sym() != nil && n.Op() != ONAME { + mode.Fprintf(s, " %v", n.Sym()) } - if n.Type != nil { - mode.Fprintf(s, " %v", n.Type) + if n.Type() != nil { + mode.Fprintf(s, " %v", n.Type()) } if recur { - if n.Left != nil { - mode.Fprintf(s, "%v", n.Left) + if n.Left() != nil { + mode.Fprintf(s, "%v", n.Left()) } - if n.Right != nil { - mode.Fprintf(s, "%v", n.Right) + if n.Right() != nil { + mode.Fprintf(s, "%v", n.Right()) } - if n.Op == OCLOSURE && n.Func != nil && n.Func.Decl != nil && n.Func.Decl.Nbody.Len() != 0 { + if n.Op() == OCLOSURE && n.Func() != nil && n.Func().Decl != nil && n.Func().Decl.Body().Len() != 0 { indent(s) // The function associated with a closure - mode.Fprintf(s, "%v-clofunc%v", n.Op, n.Func.Decl) + mode.Fprintf(s, "%v-clofunc%v", n.Op(), n.Func().Decl) } - if n.Op == ODCLFUNC && n.Func != nil && n.Func.Dcl != nil && len(n.Func.Dcl) != 0 { + if n.Op() == ODCLFUNC && n.Func() != nil && n.Func().Dcl != nil && len(n.Func().Dcl) != 0 { indent(s) // The dcls for a func or closure - mode.Fprintf(s, "%v-dcl%v", n.Op, AsNodes(n.Func.Dcl)) + mode.Fprintf(s, "%v-dcl%v", n.Op(), AsNodes(n.Func().Dcl)) } - if n.List.Len() != 0 { + if n.List().Len() != 0 { indent(s) - mode.Fprintf(s, "%v-list%v", n.Op, n.List) + mode.Fprintf(s, "%v-list%v", n.Op(), n.List()) } - if n.Rlist.Len() != 0 { + if n.Rlist().Len() != 0 { indent(s) - mode.Fprintf(s, "%v-rlist%v", n.Op, n.Rlist) + mode.Fprintf(s, "%v-rlist%v", n.Op(), n.Rlist()) } - if n.Nbody.Len() != 0 { + if n.Body().Len() != 0 { indent(s) - mode.Fprintf(s, "%v-body%v", n.Op, n.Nbody) + mode.Fprintf(s, "%v-body%v", n.Op(), n.Body()) } } } @@ -1910,5 +1910,5 @@ func InstallTypeFormats() { // Line returns n's position as a string. If n has been inlined, // it uses the outermost position where n has been inlined. func Line(n *Node) string { - return base.FmtPos(n.Pos) + return base.FmtPos(n.Pos()) } diff --git a/src/cmd/compile/internal/ir/node.go b/src/cmd/compile/internal/ir/node.go index cac9e6eb3e..dce1bfdbef 100644 --- a/src/cmd/compile/internal/ir/node.go +++ b/src/cmd/compile/internal/ir/node.go @@ -26,25 +26,25 @@ import ( type Node struct { // Tree structure. // Generic recursive walks should follow these fields. - Left *Node - Right *Node - Ninit Nodes - Nbody Nodes - List Nodes - Rlist Nodes + left *Node + right *Node + init Nodes + body Nodes + list Nodes + rlist Nodes // most nodes - Type *types.Type - Orig *Node // original form, for printing, and tracking copies of ONAMEs + typ *types.Type + orig *Node // original form, for printing, and tracking copies of ONAMEs // func - Func *Func + fn *Func // ONAME, OTYPE, OPACK, OLABEL, some OLITERAL - Name *Name + name *Name - Sym *types.Sym // various - E interface{} // Opt or Val, see methods below + sym *types.Sym // various + e interface{} // Opt or Val, see methods below // Various. Usually an offset into a struct. For example: // - ONAME nodes that refer to local variables use it to identify their stack frame position. @@ -54,85 +54,85 @@ type Node struct { // - OINLMARK stores an index into the inlTree data structure. // - OCLOSURE uses it to store ambient iota value, if any. // Possibly still more uses. If you find any, document them. - Xoffset int64 + offset int64 - Pos src.XPos + pos src.XPos flags bitset32 - Esc uint16 // EscXXX + esc uint16 // EscXXX - Op Op + op Op aux uint8 } -func (n *Node) GetLeft() *Node { return n.Left } -func (n *Node) SetLeft(x *Node) { n.Left = x } -func (n *Node) GetRight() *Node { return n.Right } -func (n *Node) SetRight(x *Node) { n.Right = x } -func (n *Node) GetOrig() *Node { return n.Orig } -func (n *Node) SetOrig(x *Node) { n.Orig = x } -func (n *Node) GetType() *types.Type { return n.Type } -func (n *Node) SetType(x *types.Type) { n.Type = x } -func (n *Node) GetFunc() *Func { return n.Func } -func (n *Node) SetFunc(x *Func) { n.Func = x } -func (n *Node) GetName() *Name { return n.Name } -func (n *Node) SetName(x *Name) { n.Name = x } -func (n *Node) GetSym() *types.Sym { return n.Sym } -func (n *Node) SetSym(x *types.Sym) { n.Sym = x } -func (n *Node) GetPos() src.XPos { return n.Pos } -func (n *Node) SetPos(x src.XPos) { n.Pos = x } -func (n *Node) GetXoffset() int64 { return n.Xoffset } -func (n *Node) SetXoffset(x int64) { n.Xoffset = x } -func (n *Node) GetEsc() uint16 { return n.Esc } -func (n *Node) SetEsc(x uint16) { n.Esc = x } -func (n *Node) GetOp() Op { return n.Op } -func (n *Node) SetOp(x Op) { n.Op = x } -func (n *Node) GetNinit() Nodes { return n.Ninit } -func (n *Node) SetNinit(x Nodes) { n.Ninit = x } -func (n *Node) PtrNinit() *Nodes { return &n.Ninit } -func (n *Node) GetNbody() Nodes { return n.Nbody } -func (n *Node) SetNbody(x Nodes) { n.Nbody = x } -func (n *Node) PtrNbody() *Nodes { return &n.Nbody } -func (n *Node) GetList() Nodes { return n.List } -func (n *Node) SetList(x Nodes) { n.List = x } -func (n *Node) PtrList() *Nodes { return &n.List } -func (n *Node) GetRlist() Nodes { return n.Rlist } -func (n *Node) SetRlist(x Nodes) { n.Rlist = x } -func (n *Node) PtrRlist() *Nodes { return &n.Rlist } +func (n *Node) Left() *Node { return n.left } +func (n *Node) SetLeft(x *Node) { n.left = x } +func (n *Node) Right() *Node { return n.right } +func (n *Node) SetRight(x *Node) { n.right = x } +func (n *Node) Orig() *Node { return n.orig } +func (n *Node) SetOrig(x *Node) { n.orig = x } +func (n *Node) Type() *types.Type { return n.typ } +func (n *Node) SetType(x *types.Type) { n.typ = x } +func (n *Node) Func() *Func { return n.fn } +func (n *Node) SetFunc(x *Func) { n.fn = x } +func (n *Node) Name() *Name { return n.name } +func (n *Node) SetName(x *Name) { n.name = x } +func (n *Node) Sym() *types.Sym { return n.sym } +func (n *Node) SetSym(x *types.Sym) { n.sym = x } +func (n *Node) Pos() src.XPos { return n.pos } +func (n *Node) SetPos(x src.XPos) { n.pos = x } +func (n *Node) Offset() int64 { return n.offset } +func (n *Node) SetOffset(x int64) { n.offset = x } +func (n *Node) Esc() uint16 { return n.esc } +func (n *Node) SetEsc(x uint16) { n.esc = x } +func (n *Node) Op() Op { return n.op } +func (n *Node) SetOp(x Op) { n.op = x } +func (n *Node) Init() Nodes { return n.init } +func (n *Node) SetInit(x Nodes) { n.init = x } +func (n *Node) PtrInit() *Nodes { return &n.init } +func (n *Node) Body() Nodes { return n.body } +func (n *Node) SetBody(x Nodes) { n.body = x } +func (n *Node) PtrBody() *Nodes { return &n.body } +func (n *Node) List() Nodes { return n.list } +func (n *Node) SetList(x Nodes) { n.list = x } +func (n *Node) PtrList() *Nodes { return &n.list } +func (n *Node) Rlist() Nodes { return n.rlist } +func (n *Node) SetRlist(x Nodes) { n.rlist = x } +func (n *Node) PtrRlist() *Nodes { return &n.rlist } func (n *Node) ResetAux() { n.aux = 0 } func (n *Node) SubOp() Op { - switch n.Op { + switch n.Op() { case OASOP, ONAME: default: - base.Fatalf("unexpected op: %v", n.Op) + base.Fatalf("unexpected op: %v", n.Op()) } return Op(n.aux) } func (n *Node) SetSubOp(op Op) { - switch n.Op { + switch n.Op() { case OASOP, ONAME: default: - base.Fatalf("unexpected op: %v", n.Op) + base.Fatalf("unexpected op: %v", n.Op()) } n.aux = uint8(op) } func (n *Node) IndexMapLValue() bool { - if n.Op != OINDEXMAP { - base.Fatalf("unexpected op: %v", n.Op) + if n.Op() != OINDEXMAP { + base.Fatalf("unexpected op: %v", n.Op()) } return n.aux != 0 } func (n *Node) SetIndexMapLValue(b bool) { - if n.Op != OINDEXMAP { - base.Fatalf("unexpected op: %v", n.Op) + if n.Op() != OINDEXMAP { + base.Fatalf("unexpected op: %v", n.Op()) } if b { n.aux = 1 @@ -142,31 +142,31 @@ func (n *Node) SetIndexMapLValue(b bool) { } func (n *Node) TChanDir() types.ChanDir { - if n.Op != OTCHAN { - base.Fatalf("unexpected op: %v", n.Op) + if n.Op() != OTCHAN { + base.Fatalf("unexpected op: %v", n.Op()) } return types.ChanDir(n.aux) } func (n *Node) SetTChanDir(dir types.ChanDir) { - if n.Op != OTCHAN { - base.Fatalf("unexpected op: %v", n.Op) + if n.Op() != OTCHAN { + base.Fatalf("unexpected op: %v", n.Op()) } n.aux = uint8(dir) } func IsSynthetic(n *Node) bool { - name := n.Sym.Name + name := n.Sym().Name return name[0] == '.' || name[0] == '~' } // IsAutoTmp indicates if n was created by the compiler as a temporary, // based on the setting of the .AutoTemp flag in n's Name. func IsAutoTmp(n *Node) bool { - if n == nil || n.Op != ONAME { + if n == nil || n.Op() != ONAME { return false } - return n.Name.AutoTemp() + return n.Name().AutoTemp() } const ( @@ -229,8 +229,8 @@ func (n *Node) SetColas(b bool) { n.flags.set(nodeColas, b) } func (n *Node) SetTransient(b bool) { n.flags.set(nodeTransient, b) } func (n *Node) SetHasCall(b bool) { n.flags.set(nodeHasCall, b) } func (n *Node) SetLikely(b bool) { n.flags.set(nodeLikely, b) } -func (n *Node) SetHasVal(b bool) { n.flags.set(nodeHasVal, b) } -func (n *Node) SetHasOpt(b bool) { n.flags.set(nodeHasOpt, b) } +func (n *Node) setHasVal(b bool) { n.flags.set(nodeHasVal, b) } +func (n *Node) setHasOpt(b bool) { n.flags.set(nodeHasOpt, b) } func (n *Node) SetEmbedded(b bool) { n.flags.set(nodeEmbedded, b) } // MarkNonNil marks a pointer n as being guaranteed non-nil, @@ -238,8 +238,8 @@ func (n *Node) SetEmbedded(b bool) { n.flags.set(nodeEmbedded, b) } // During conversion to SSA, non-nil pointers won't have nil checks // inserted before dereferencing. See state.exprPtr. func (n *Node) MarkNonNil() { - if !n.Type.IsPtr() && !n.Type.IsUnsafePtr() { - base.Fatalf("MarkNonNil(%v), type %v", n, n.Type) + if !n.Type().IsPtr() && !n.Type().IsUnsafePtr() { + base.Fatalf("MarkNonNil(%v), type %v", n, n.Type()) } n.flags.set(nodeNonNil, true) } @@ -249,7 +249,7 @@ func (n *Node) MarkNonNil() { // When n is a dereferencing operation, n does not need nil checks. // When n is a makeslice+copy operation, n does not need length and cap checks. func (n *Node) SetBounded(b bool) { - switch n.Op { + switch n.Op() { case OINDEX, OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR: // No bounds checks needed. case ODOTPTR, ODEREF: @@ -265,14 +265,14 @@ func (n *Node) SetBounded(b bool) { // MarkReadonly indicates that n is an ONAME with readonly contents. func (n *Node) MarkReadonly() { - if n.Op != ONAME { - base.Fatalf("Node.MarkReadonly %v", n.Op) + if n.Op() != ONAME { + base.Fatalf("Node.MarkReadonly %v", n.Op()) } - n.Name.SetReadonly(true) + n.Name().SetReadonly(true) // Mark the linksym as readonly immediately // so that the SSA backend can use this information. // It will be overridden later during dumpglobls. - n.Sym.Linksym().Type = objabi.SRODATA + n.Sym().Linksym().Type = objabi.SRODATA } // Val returns the constant.Value for the node. @@ -280,7 +280,7 @@ func (n *Node) Val() constant.Value { if !n.HasVal() { return constant.MakeUnknown() } - return *n.E.(*constant.Value) + return *n.e.(*constant.Value) } // SetVal sets the constant.Value for the node, @@ -291,11 +291,11 @@ func (n *Node) SetVal(v constant.Value) { Dump("have Opt", n) base.Fatalf("have Opt") } - if n.Op == OLITERAL { - AssertValidTypeForConst(n.Type, v) + if n.Op() == OLITERAL { + AssertValidTypeForConst(n.Type(), v) } - n.SetHasVal(true) - n.E = &v + n.setHasVal(true) + n.e = &v } // Opt returns the optimizer data for the node. @@ -303,7 +303,7 @@ func (n *Node) Opt() interface{} { if !n.HasOpt() { return nil } - return n.E + return n.e } // SetOpt sets the optimizer data for the node, which must not have been used with SetVal. @@ -311,8 +311,8 @@ func (n *Node) Opt() interface{} { func (n *Node) SetOpt(x interface{}) { if x == nil { if n.HasOpt() { - n.SetHasOpt(false) - n.E = nil + n.setHasOpt(false) + n.e = nil } return } @@ -321,22 +321,22 @@ func (n *Node) SetOpt(x interface{}) { Dump("have Val", n) base.Fatalf("have Val") } - n.SetHasOpt(true) - n.E = x + n.setHasOpt(true) + n.e = x } func (n *Node) Iota() int64 { - return n.Xoffset + return n.Offset() } func (n *Node) SetIota(x int64) { - n.Xoffset = x + n.SetOffset(x) } // mayBeShared reports whether n may occur in multiple places in the AST. // Extra care must be taken when mutating such a node. func MayBeShared(n *Node) bool { - switch n.Op { + switch n.Op() { case ONAME, OLITERAL, ONIL, OTYPE: return true } @@ -345,10 +345,10 @@ func MayBeShared(n *Node) bool { // funcname returns the name (without the package) of the function n. func FuncName(n *Node) string { - if n == nil || n.Func == nil || n.Func.Nname == nil { + if n == nil || n.Func() == nil || n.Func().Nname == nil { return "" } - return n.Func.Nname.Sym.Name + return n.Func().Nname.Sym().Name } // pkgFuncName returns the name of the function referenced by n, with package prepended. @@ -360,13 +360,13 @@ func PkgFuncName(n *Node) string { if n == nil { return "" } - if n.Op == ONAME { - s = n.Sym + if n.Op() == ONAME { + s = n.Sym() } else { - if n.Func == nil || n.Func.Nname == nil { + if n.Func() == nil || n.Func().Nname == nil { return "" } - s = n.Func.Nname.Sym + s = n.Func().Nname.Sym() } pkg := s.Pkg @@ -1142,12 +1142,12 @@ func Inspect(n *Node, f func(*Node) bool) { if n == nil || !f(n) { return } - InspectList(n.Ninit, f) - Inspect(n.Left, f) - Inspect(n.Right, f) - InspectList(n.List, f) - InspectList(n.Nbody, f) - InspectList(n.Rlist, f) + InspectList(n.Init(), f) + Inspect(n.Left(), f) + Inspect(n.Right(), f) + InspectList(n.List(), f) + InspectList(n.Body(), f) + InspectList(n.Rlist(), f) } func InspectList(l Nodes, f func(*Node) bool) { @@ -1242,8 +1242,8 @@ func NodAt(pos src.XPos, op Op, nleft, nright *Node) *Node { f Func } n = &x.n - n.Func = &x.f - n.Func.Decl = n + n.SetFunc(&x.f) + n.Func().Decl = n case ONAME: base.Fatalf("use newname instead") case OLABEL, OPACK: @@ -1252,16 +1252,16 @@ func NodAt(pos src.XPos, op Op, nleft, nright *Node) *Node { m Name } n = &x.n - n.Name = &x.m + n.SetName(&x.m) default: n = new(Node) } - n.Op = op - n.Left = nleft - n.Right = nright - n.Pos = pos - n.Xoffset = types.BADWIDTH - n.Orig = n + n.SetOp(op) + n.SetLeft(nleft) + n.SetRight(nright) + n.SetPos(pos) + n.SetOffset(types.BADWIDTH) + n.SetOrig(n) return n } @@ -1278,14 +1278,14 @@ func NewNameAt(pos src.XPos, s *types.Sym) *Node { p Param } n := &x.n - n.Name = &x.m - n.Name.Param = &x.p + n.SetName(&x.m) + n.Name().Param = &x.p - n.Op = ONAME - n.Pos = pos - n.Orig = n + n.SetOp(ONAME) + n.SetPos(pos) + n.SetOrig(n) - n.Sym = s + n.SetSym(s) return n } @@ -1358,7 +1358,7 @@ func OrigSym(s *types.Sym) *types.Sym { return nil case 'b': // originally the blank identifier _ // TODO(mdempsky): Does s.Pkg matter here? - return BlankNode.Sym + return BlankNode.Sym() } return s } @@ -1374,48 +1374,48 @@ func OrigSym(s *types.Sym) *types.Sym { // SliceBounds returns n's slice bounds: low, high, and max in expr[low:high:max]. // n must be a slice expression. max is nil if n is a simple slice expression. func (n *Node) SliceBounds() (low, high, max *Node) { - if n.List.Len() == 0 { + if n.List().Len() == 0 { return nil, nil, nil } - switch n.Op { + switch n.Op() { case OSLICE, OSLICEARR, OSLICESTR: - s := n.List.Slice() + s := n.List().Slice() return s[0], s[1], nil case OSLICE3, OSLICE3ARR: - s := n.List.Slice() + s := n.List().Slice() return s[0], s[1], s[2] } - base.Fatalf("SliceBounds op %v: %v", n.Op, n) + base.Fatalf("SliceBounds op %v: %v", n.Op(), n) return nil, nil, nil } // SetSliceBounds sets n's slice bounds, where n is a slice expression. // n must be a slice expression. If max is non-nil, n must be a full slice expression. func (n *Node) SetSliceBounds(low, high, max *Node) { - switch n.Op { + switch n.Op() { case OSLICE, OSLICEARR, OSLICESTR: if max != nil { - base.Fatalf("SetSliceBounds %v given three bounds", n.Op) + base.Fatalf("SetSliceBounds %v given three bounds", n.Op()) } - s := n.List.Slice() + s := n.List().Slice() if s == nil { if low == nil && high == nil { return } - n.List.Set2(low, high) + n.PtrList().Set2(low, high) return } s[0] = low s[1] = high return case OSLICE3, OSLICE3ARR: - s := n.List.Slice() + s := n.List().Slice() if s == nil { if low == nil && high == nil && max == nil { return } - n.List.Set3(low, high, max) + n.PtrList().Set3(low, high, max) return } s[0] = low @@ -1423,7 +1423,7 @@ func (n *Node) SetSliceBounds(low, high, max *Node) { s[2] = max return } - base.Fatalf("SetSliceBounds op %v: %v", n.Op, n) + base.Fatalf("SetSliceBounds op %v: %v", n.Op(), n) } // IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR). @@ -1511,7 +1511,7 @@ func (n *Node) RawCopy() *Node { // Orig pointing to itself. func SepCopy(n *Node) *Node { copy := *n - copy.Orig = © + copy.orig = © return © } @@ -1524,8 +1524,8 @@ func SepCopy(n *Node) *Node { // messages; see issues #26855, #27765). func Copy(n *Node) *Node { copy := *n - if n.Orig == n { - copy.Orig = © + if n.Orig() == n { + copy.orig = © } return © } @@ -1534,18 +1534,18 @@ func Copy(n *Node) *Node { func IsNil(n *Node) bool { // Check n.Orig because constant propagation may produce typed nil constants, // which don't exist in the Go spec. - return n.Orig.Op == ONIL + return n.Orig().Op() == ONIL } func IsBlank(n *Node) bool { if n == nil { return false } - return n.Sym.IsBlank() + return n.Sym().IsBlank() } // IsMethod reports whether n is a method. // n must be a function or a method. func IsMethod(n *Node) bool { - return n.Type.Recv() != nil + return n.Type().Recv() != nil } diff --git a/src/cmd/compile/internal/ir/val.go b/src/cmd/compile/internal/ir/val.go index 00b5bfd1ad..6bcee7c01c 100644 --- a/src/cmd/compile/internal/ir/val.go +++ b/src/cmd/compile/internal/ir/val.go @@ -13,7 +13,7 @@ import ( ) func ConstType(n *Node) constant.Kind { - if n == nil || n.Op != OLITERAL { + if n == nil || n.Op() != OLITERAL { return constant.Unknown } return n.Val().Kind() @@ -32,7 +32,7 @@ func ConstValue(n *Node) interface{} { case constant.String: return constant.StringVal(v) case constant.Int: - return Int64Val(n.Type, v) + return Int64Val(n.Type(), v) case constant.Float: return Float64Val(v) case constant.Complex: @@ -94,7 +94,7 @@ func ValidTypeForConst(t *types.Type, v constant.Value) bool { func NewLiteral(v constant.Value) *Node { n := Nod(OLITERAL, nil, nil) if k := v.Kind(); k != constant.Unknown { - n.Type = idealType(k) + n.SetType(idealType(k)) n.SetVal(v) } return n diff --git a/src/cmd/compile/internal/ssa/nilcheck.go b/src/cmd/compile/internal/ssa/nilcheck.go index e0ae0454ef..3c1fa600a3 100644 --- a/src/cmd/compile/internal/ssa/nilcheck.go +++ b/src/cmd/compile/internal/ssa/nilcheck.go @@ -236,7 +236,7 @@ func nilcheckelim2(f *Func) { continue } if v.Type.IsMemory() || v.Type.IsTuple() && v.Type.FieldType(1).IsMemory() { - if v.Op == OpVarKill || v.Op == OpVarLive || (v.Op == OpVarDef && !v.Aux.(*ir.Node).Type.HasPointers()) { + if v.Op == OpVarKill || v.Op == OpVarLive || (v.Op == OpVarDef && !v.Aux.(*ir.Node).Type().HasPointers()) { // These ops don't really change memory. continue // Note: OpVarDef requires that the defined variable not have pointers. -- 2.48.1