mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[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 <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
41ab6689ed
commit
acb4d1cef1
44 changed files with 5188 additions and 5186 deletions
|
|
@ -293,15 +293,15 @@ func genhash(t *types.Type) *obj.LSym {
|
||||||
|
|
||||||
// func sym(p *T, h uintptr) uintptr
|
// func sym(p *T, h uintptr) uintptr
|
||||||
tfn := ir.Nod(ir.OTFUNC, nil, nil)
|
tfn := ir.Nod(ir.OTFUNC, nil, nil)
|
||||||
tfn.List.Set2(
|
tfn.PtrList().Set2(
|
||||||
namedfield("p", types.NewPtr(t)),
|
namedfield("p", types.NewPtr(t)),
|
||||||
namedfield("h", types.Types[types.TUINTPTR]),
|
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)
|
fn := dclfunc(sym, tfn)
|
||||||
np := ir.AsNode(tfn.Type.Params().Field(0).Nname)
|
np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
|
||||||
nh := ir.AsNode(tfn.Type.Params().Field(1).Nname)
|
nh := ir.AsNode(tfn.Type().Params().Field(1).Nname)
|
||||||
|
|
||||||
switch t.Etype {
|
switch t.Etype {
|
||||||
case types.TARRAY:
|
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))
|
n := ir.Nod(ir.ORANGE, nil, ir.Nod(ir.ODEREF, np, nil))
|
||||||
ni := NewName(lookup("i"))
|
ni := NewName(lookup("i"))
|
||||||
ni.Type = types.Types[types.TINT]
|
ni.SetType(types.Types[types.TINT])
|
||||||
n.List.Set1(ni)
|
n.PtrList().Set1(ni)
|
||||||
n.SetColas(true)
|
n.SetColas(true)
|
||||||
colasdefn(n.List.Slice(), n)
|
colasdefn(n.List().Slice(), n)
|
||||||
ni = n.List.First()
|
ni = n.List().First()
|
||||||
|
|
||||||
// h = hashel(&p[i], h)
|
// h = hashel(&p[i], h)
|
||||||
call := ir.Nod(ir.OCALL, hashel, nil)
|
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 := ir.Nod(ir.OINDEX, np, ni)
|
||||||
nx.SetBounded(true)
|
nx.SetBounded(true)
|
||||||
na := ir.Nod(ir.OADDR, nx, nil)
|
na := ir.Nod(ir.OADDR, nx, nil)
|
||||||
call.List.Append(na)
|
call.PtrList().Append(na)
|
||||||
call.List.Append(nh)
|
call.PtrList().Append(nh)
|
||||||
n.Nbody.Append(ir.Nod(ir.OAS, nh, call))
|
n.PtrBody().Append(ir.Nod(ir.OAS, nh, call))
|
||||||
|
|
||||||
fn.Nbody.Append(n)
|
fn.PtrBody().Append(n)
|
||||||
|
|
||||||
case types.TSTRUCT:
|
case types.TSTRUCT:
|
||||||
// Walk the struct using memhash for runs of AMEM
|
// 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)
|
call := ir.Nod(ir.OCALL, hashel, nil)
|
||||||
nx := nodSym(ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
|
nx := nodSym(ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
|
||||||
na := ir.Nod(ir.OADDR, nx, nil)
|
na := ir.Nod(ir.OADDR, nx, nil)
|
||||||
call.List.Append(na)
|
call.PtrList().Append(na)
|
||||||
call.List.Append(nh)
|
call.PtrList().Append(nh)
|
||||||
fn.Nbody.Append(ir.Nod(ir.OAS, nh, call))
|
fn.PtrBody().Append(ir.Nod(ir.OAS, nh, call))
|
||||||
i++
|
i++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -363,37 +363,37 @@ func genhash(t *types.Type) *obj.LSym {
|
||||||
call := ir.Nod(ir.OCALL, hashel, nil)
|
call := ir.Nod(ir.OCALL, hashel, nil)
|
||||||
nx := nodSym(ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
|
nx := nodSym(ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
|
||||||
na := ir.Nod(ir.OADDR, nx, nil)
|
na := ir.Nod(ir.OADDR, nx, nil)
|
||||||
call.List.Append(na)
|
call.PtrList().Append(na)
|
||||||
call.List.Append(nh)
|
call.PtrList().Append(nh)
|
||||||
call.List.Append(nodintconst(size))
|
call.PtrList().Append(nodintconst(size))
|
||||||
fn.Nbody.Append(ir.Nod(ir.OAS, nh, call))
|
fn.PtrBody().Append(ir.Nod(ir.OAS, nh, call))
|
||||||
|
|
||||||
i = next
|
i = next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r := ir.Nod(ir.ORETURN, nil, nil)
|
r := ir.Nod(ir.ORETURN, nil, nil)
|
||||||
r.List.Append(nh)
|
r.PtrList().Append(nh)
|
||||||
fn.Nbody.Append(r)
|
fn.PtrBody().Append(r)
|
||||||
|
|
||||||
if base.Flag.LowerR != 0 {
|
if base.Flag.LowerR != 0 {
|
||||||
ir.DumpList("genhash body", fn.Nbody)
|
ir.DumpList("genhash body", fn.Body())
|
||||||
}
|
}
|
||||||
|
|
||||||
funcbody()
|
funcbody()
|
||||||
|
|
||||||
fn.Func.SetDupok(true)
|
fn.Func().SetDupok(true)
|
||||||
fn = typecheck(fn, ctxStmt)
|
fn = typecheck(fn, ctxStmt)
|
||||||
|
|
||||||
Curfn = fn
|
Curfn = fn
|
||||||
typecheckslice(fn.Nbody.Slice(), ctxStmt)
|
typecheckslice(fn.Body().Slice(), ctxStmt)
|
||||||
Curfn = nil
|
Curfn = nil
|
||||||
|
|
||||||
if base.Debug.DclStack != 0 {
|
if base.Debug.DclStack != 0 {
|
||||||
testdclstack()
|
testdclstack()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn.Func.SetNilCheckDisabled(true)
|
fn.Func().SetNilCheckDisabled(true)
|
||||||
xtop = append(xtop, fn)
|
xtop = append(xtop, fn)
|
||||||
|
|
||||||
// Build closure. It doesn't close over any variables, so
|
// Build closure. It doesn't close over any variables, so
|
||||||
|
|
@ -432,12 +432,12 @@ func hashfor(t *types.Type) *ir.Node {
|
||||||
|
|
||||||
n := NewName(sym)
|
n := NewName(sym)
|
||||||
setNodeNameFunc(n)
|
setNodeNameFunc(n)
|
||||||
n.Type = functype(nil, []*ir.Node{
|
n.SetType(functype(nil, []*ir.Node{
|
||||||
anonfield(types.NewPtr(t)),
|
anonfield(types.NewPtr(t)),
|
||||||
anonfield(types.Types[types.TUINTPTR]),
|
anonfield(types.Types[types.TUINTPTR]),
|
||||||
}, []*ir.Node{
|
}, []*ir.Node{
|
||||||
anonfield(types.Types[types.TUINTPTR]),
|
anonfield(types.Types[types.TUINTPTR]),
|
||||||
})
|
}))
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -522,16 +522,16 @@ func geneq(t *types.Type) *obj.LSym {
|
||||||
|
|
||||||
// func sym(p, q *T) bool
|
// func sym(p, q *T) bool
|
||||||
tfn := ir.Nod(ir.OTFUNC, nil, nil)
|
tfn := ir.Nod(ir.OTFUNC, nil, nil)
|
||||||
tfn.List.Set2(
|
tfn.PtrList().Set2(
|
||||||
namedfield("p", types.NewPtr(t)),
|
namedfield("p", types.NewPtr(t)),
|
||||||
namedfield("q", 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)
|
fn := dclfunc(sym, tfn)
|
||||||
np := ir.AsNode(tfn.Type.Params().Field(0).Nname)
|
np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
|
||||||
nq := ir.AsNode(tfn.Type.Params().Field(1).Nname)
|
nq := ir.AsNode(tfn.Type().Params().Field(1).Nname)
|
||||||
nr := ir.AsNode(tfn.Type.Results().Field(0).Nname)
|
nr := ir.AsNode(tfn.Type().Results().Field(0).Nname)
|
||||||
|
|
||||||
// Label to jump to if an equality test fails.
|
// Label to jump to if an equality test fails.
|
||||||
neq := autolabel(".neq")
|
neq := autolabel(".neq")
|
||||||
|
|
@ -573,11 +573,11 @@ func geneq(t *types.Type) *obj.LSym {
|
||||||
// pi := p[i]
|
// pi := p[i]
|
||||||
pi := ir.Nod(ir.OINDEX, np, i)
|
pi := ir.Nod(ir.OINDEX, np, i)
|
||||||
pi.SetBounded(true)
|
pi.SetBounded(true)
|
||||||
pi.Type = t.Elem()
|
pi.SetType(t.Elem())
|
||||||
// qi := q[i]
|
// qi := q[i]
|
||||||
qi := ir.Nod(ir.OINDEX, nq, i)
|
qi := ir.Nod(ir.OINDEX, nq, i)
|
||||||
qi.SetBounded(true)
|
qi.SetBounded(true)
|
||||||
qi.Type = t.Elem()
|
qi.SetType(t.Elem())
|
||||||
return eq(pi, qi)
|
return eq(pi, qi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -590,11 +590,11 @@ func geneq(t *types.Type) *obj.LSym {
|
||||||
for i := int64(0); i < nelem; i++ {
|
for i := int64(0); i < nelem; i++ {
|
||||||
// if check {} else { goto neq }
|
// if check {} else { goto neq }
|
||||||
nif := ir.Nod(ir.OIF, checkIdx(nodintconst(i)), nil)
|
nif := ir.Nod(ir.OIF, checkIdx(nodintconst(i)), nil)
|
||||||
nif.Rlist.Append(nodSym(ir.OGOTO, nil, neq))
|
nif.PtrRlist().Append(nodSym(ir.OGOTO, nil, neq))
|
||||||
fn.Nbody.Append(nif)
|
fn.PtrBody().Append(nif)
|
||||||
}
|
}
|
||||||
if last {
|
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 {
|
} else {
|
||||||
// Generate a for loop.
|
// Generate a for loop.
|
||||||
|
|
@ -604,14 +604,14 @@ func geneq(t *types.Type) *obj.LSym {
|
||||||
cond := ir.Nod(ir.OLT, i, nodintconst(nelem))
|
cond := ir.Nod(ir.OLT, i, nodintconst(nelem))
|
||||||
post := ir.Nod(ir.OAS, i, ir.Nod(ir.OADD, i, nodintconst(1)))
|
post := ir.Nod(ir.OAS, i, ir.Nod(ir.OADD, i, nodintconst(1)))
|
||||||
loop := ir.Nod(ir.OFOR, cond, post)
|
loop := ir.Nod(ir.OFOR, cond, post)
|
||||||
loop.Ninit.Append(init)
|
loop.PtrInit().Append(init)
|
||||||
// if eq(pi, qi) {} else { goto neq }
|
// if eq(pi, qi) {} else { goto neq }
|
||||||
nif := ir.Nod(ir.OIF, checkIdx(i), nil)
|
nif := ir.Nod(ir.OIF, checkIdx(i), nil)
|
||||||
nif.Rlist.Append(nodSym(ir.OGOTO, nil, neq))
|
nif.PtrRlist().Append(nodSym(ir.OGOTO, nil, neq))
|
||||||
loop.Nbody.Append(nif)
|
loop.PtrBody().Append(nif)
|
||||||
fn.Nbody.Append(loop)
|
fn.PtrBody().Append(loop)
|
||||||
if last {
|
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
|
var flatConds []*ir.Node
|
||||||
for _, c := range conds {
|
for _, c := range conds {
|
||||||
isCall := func(n *ir.Node) bool {
|
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 {
|
sort.SliceStable(c, func(i, j int) bool {
|
||||||
return !isCall(c[i]) && isCall(c[j])
|
return !isCall(c[i]) && isCall(c[j])
|
||||||
|
|
@ -721,51 +721,51 @@ func geneq(t *types.Type) *obj.LSym {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flatConds) == 0 {
|
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 {
|
} else {
|
||||||
for _, c := range flatConds[:len(flatConds)-1] {
|
for _, c := range flatConds[:len(flatConds)-1] {
|
||||||
// if cond {} else { goto neq }
|
// if cond {} else { goto neq }
|
||||||
n := ir.Nod(ir.OIF, c, nil)
|
n := ir.Nod(ir.OIF, c, nil)
|
||||||
n.Rlist.Append(nodSym(ir.OGOTO, nil, neq))
|
n.PtrRlist().Append(nodSym(ir.OGOTO, nil, neq))
|
||||||
fn.Nbody.Append(n)
|
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:
|
// ret:
|
||||||
// return
|
// return
|
||||||
ret := autolabel(".ret")
|
ret := autolabel(".ret")
|
||||||
fn.Nbody.Append(nodSym(ir.OLABEL, nil, ret))
|
fn.PtrBody().Append(nodSym(ir.OLABEL, nil, ret))
|
||||||
fn.Nbody.Append(ir.Nod(ir.ORETURN, nil, nil))
|
fn.PtrBody().Append(ir.Nod(ir.ORETURN, nil, nil))
|
||||||
|
|
||||||
// neq:
|
// neq:
|
||||||
// r = false
|
// r = false
|
||||||
// return (or goto ret)
|
// return (or goto ret)
|
||||||
fn.Nbody.Append(nodSym(ir.OLABEL, nil, neq))
|
fn.PtrBody().Append(nodSym(ir.OLABEL, nil, neq))
|
||||||
fn.Nbody.Append(ir.Nod(ir.OAS, nr, nodbool(false)))
|
fn.PtrBody().Append(ir.Nod(ir.OAS, nr, nodbool(false)))
|
||||||
if EqCanPanic(t) || hasCall(fn) {
|
if EqCanPanic(t) || hasCall(fn) {
|
||||||
// Epilogue is large, so share it with the equal case.
|
// 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 {
|
} else {
|
||||||
// Epilogue is small, so don't bother sharing.
|
// 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.
|
// TODO(khr): the epilogue size detection condition above isn't perfect.
|
||||||
// We should really do a generic CL that shares epilogues across
|
// We should really do a generic CL that shares epilogues across
|
||||||
// the board. See #24936.
|
// the board. See #24936.
|
||||||
|
|
||||||
if base.Flag.LowerR != 0 {
|
if base.Flag.LowerR != 0 {
|
||||||
ir.DumpList("geneq body", fn.Nbody)
|
ir.DumpList("geneq body", fn.Body())
|
||||||
}
|
}
|
||||||
|
|
||||||
funcbody()
|
funcbody()
|
||||||
|
|
||||||
fn.Func.SetDupok(true)
|
fn.Func().SetDupok(true)
|
||||||
fn = typecheck(fn, ctxStmt)
|
fn = typecheck(fn, ctxStmt)
|
||||||
|
|
||||||
Curfn = fn
|
Curfn = fn
|
||||||
typecheckslice(fn.Nbody.Slice(), ctxStmt)
|
typecheckslice(fn.Body().Slice(), ctxStmt)
|
||||||
Curfn = nil
|
Curfn = nil
|
||||||
|
|
||||||
if base.Debug.DclStack != 0 {
|
if base.Debug.DclStack != 0 {
|
||||||
|
|
@ -776,7 +776,7 @@ func geneq(t *types.Type) *obj.LSym {
|
||||||
// We are comparing a struct or an array,
|
// We are comparing a struct or an array,
|
||||||
// neither of which can be nil, and our comparisons
|
// neither of which can be nil, and our comparisons
|
||||||
// are shallow.
|
// are shallow.
|
||||||
fn.Func.SetNilCheckDisabled(true)
|
fn.Func().SetNilCheckDisabled(true)
|
||||||
xtop = append(xtop, fn)
|
xtop = append(xtop, fn)
|
||||||
|
|
||||||
// Generate a closure which points at the function we just generated.
|
// 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 {
|
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
|
return true
|
||||||
}
|
}
|
||||||
if n.Left != nil && hasCall(n.Left) {
|
if n.Left() != nil && hasCall(n.Left()) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if n.Right != nil && hasCall(n.Right) {
|
if n.Right() != nil && hasCall(n.Right()) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
for _, x := range n.Ninit.Slice() {
|
for _, x := range n.Init().Slice() {
|
||||||
if hasCall(x) {
|
if hasCall(x) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, x := range n.Nbody.Slice() {
|
for _, x := range n.Body().Slice() {
|
||||||
if hasCall(x) {
|
if hasCall(x) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, x := range n.List.Slice() {
|
for _, x := range n.List().Slice() {
|
||||||
if hasCall(x) {
|
if hasCall(x) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, x := range n.Rlist.Slice() {
|
for _, x := range n.Rlist().Slice() {
|
||||||
if hasCall(x) {
|
if hasCall(x) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -844,12 +844,12 @@ func eqstring(s, t *ir.Node) (eqlen, eqmem *ir.Node) {
|
||||||
fn := syslook("memequal")
|
fn := syslook("memequal")
|
||||||
fn = substArgTypes(fn, types.Types[types.TUINT8], types.Types[types.TUINT8])
|
fn = substArgTypes(fn, types.Types[types.TUINT8], types.Types[types.TUINT8])
|
||||||
call := ir.Nod(ir.OCALL, fn, nil)
|
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)
|
call = typecheck(call, ctxExpr|ctxMultiOK)
|
||||||
|
|
||||||
cmp := ir.Nod(ir.OEQ, slen, tlen)
|
cmp := ir.Nod(ir.OEQ, slen, tlen)
|
||||||
cmp = typecheck(cmp, ctxExpr)
|
cmp = typecheck(cmp, ctxExpr)
|
||||||
cmp.Type = types.Types[types.TBOOL]
|
cmp.SetType(types.Types[types.TBOOL])
|
||||||
return cmp, call
|
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.
|
// which can be used to construct interface equality comparison.
|
||||||
// eqtab must be evaluated before eqdata, and shortcircuiting is required.
|
// eqtab must be evaluated before eqdata, and shortcircuiting is required.
|
||||||
func eqinterface(s, t *ir.Node) (eqtab, eqdata *ir.Node) {
|
func eqinterface(s, t *ir.Node) (eqtab, eqdata *ir.Node) {
|
||||||
if !types.Identical(s.Type, t.Type) {
|
if !types.Identical(s.Type(), t.Type()) {
|
||||||
base.Fatalf("eqinterface %v %v", s.Type, t.Type)
|
base.Fatalf("eqinterface %v %v", s.Type(), t.Type())
|
||||||
}
|
}
|
||||||
// func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
|
// func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
|
||||||
// func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
|
// func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
|
||||||
var fn *ir.Node
|
var fn *ir.Node
|
||||||
if s.Type.IsEmptyInterface() {
|
if s.Type().IsEmptyInterface() {
|
||||||
fn = syslook("efaceeq")
|
fn = syslook("efaceeq")
|
||||||
} else {
|
} else {
|
||||||
fn = syslook("ifaceeq")
|
fn = syslook("ifaceeq")
|
||||||
|
|
@ -876,18 +876,18 @@ func eqinterface(s, t *ir.Node) (eqtab, eqdata *ir.Node) {
|
||||||
ttab := ir.Nod(ir.OITAB, t, nil)
|
ttab := ir.Nod(ir.OITAB, t, nil)
|
||||||
sdata := ir.Nod(ir.OIDATA, s, nil)
|
sdata := ir.Nod(ir.OIDATA, s, nil)
|
||||||
tdata := ir.Nod(ir.OIDATA, t, nil)
|
tdata := ir.Nod(ir.OIDATA, t, nil)
|
||||||
sdata.Type = types.Types[types.TUNSAFEPTR]
|
sdata.SetType(types.Types[types.TUNSAFEPTR])
|
||||||
tdata.Type = types.Types[types.TUNSAFEPTR]
|
tdata.SetType(types.Types[types.TUNSAFEPTR])
|
||||||
sdata.SetTypecheck(1)
|
sdata.SetTypecheck(1)
|
||||||
tdata.SetTypecheck(1)
|
tdata.SetTypecheck(1)
|
||||||
|
|
||||||
call := ir.Nod(ir.OCALL, fn, nil)
|
call := ir.Nod(ir.OCALL, fn, nil)
|
||||||
call.List.Append(stab, sdata, tdata)
|
call.PtrList().Append(stab, sdata, tdata)
|
||||||
call = typecheck(call, ctxExpr|ctxMultiOK)
|
call = typecheck(call, ctxExpr|ctxMultiOK)
|
||||||
|
|
||||||
cmp := ir.Nod(ir.OEQ, stab, ttab)
|
cmp := ir.Nod(ir.OEQ, stab, ttab)
|
||||||
cmp = typecheck(cmp, ctxExpr)
|
cmp = typecheck(cmp, ctxExpr)
|
||||||
cmp.Type = types.Types[types.TBOOL]
|
cmp.SetType(types.Types[types.TBOOL])
|
||||||
return cmp, call
|
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)
|
nx = typecheck(nx, ctxExpr)
|
||||||
ny = typecheck(ny, 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 := ir.Nod(ir.OCALL, fn, nil)
|
||||||
call.List.Append(nx)
|
call.PtrList().Append(nx)
|
||||||
call.List.Append(ny)
|
call.PtrList().Append(ny)
|
||||||
if needsize {
|
if needsize {
|
||||||
call.List.Append(nodintconst(size))
|
call.PtrList().Append(nodintconst(size))
|
||||||
}
|
}
|
||||||
|
|
||||||
return call
|
return call
|
||||||
|
|
|
||||||
|
|
@ -126,11 +126,11 @@ func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 {
|
||||||
// NOTE(rsc): This comment may be stale.
|
// NOTE(rsc): This comment may be stale.
|
||||||
// It's possible the ordering has changed and this is
|
// It's possible the ordering has changed and this is
|
||||||
// now the common case. I'm not sure.
|
// now the common case. I'm not sure.
|
||||||
if n.Name.Param.Stackcopy != nil {
|
if n.Name().Param.Stackcopy != nil {
|
||||||
n.Name.Param.Stackcopy.Xoffset = o
|
n.Name().Param.Stackcopy.SetOffset(o)
|
||||||
n.Xoffset = 0
|
n.SetOffset(0)
|
||||||
} else {
|
} else {
|
||||||
n.Xoffset = o
|
n.SetOffset(o)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,7 +198,7 @@ func findTypeLoop(t *types.Type, path *[]*types.Type) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
*path = append(*path, t)
|
*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
|
return true
|
||||||
}
|
}
|
||||||
*path = (*path)[:len(*path)-1]
|
*path = (*path)[:len(*path)-1]
|
||||||
|
|
@ -308,7 +308,7 @@ func dowidth(t *types.Type) {
|
||||||
|
|
||||||
lno := base.Pos
|
lno := base.Pos
|
||||||
if ir.AsNode(t.Nod) != nil {
|
if ir.AsNode(t.Nod) != nil {
|
||||||
base.Pos = ir.AsNode(t.Nod).Pos
|
base.Pos = ir.AsNode(t.Nod).Pos()
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Width = -2
|
t.Width = -2
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@ type exporter struct {
|
||||||
|
|
||||||
// markObject visits a reachable object.
|
// markObject visits a reachable object.
|
||||||
func (p *exporter) markObject(n *ir.Node) {
|
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)
|
inlFlood(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.markType(n.Type)
|
p.markType(n.Type())
|
||||||
}
|
}
|
||||||
|
|
||||||
// markType recursively visits types reachable from t to identify
|
// markType recursively visits types reachable from t to identify
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func npos(pos src.XPos, n *ir.Node) *ir.Node {
|
func npos(pos src.XPos, n *ir.Node) *ir.Node {
|
||||||
n.Pos = pos
|
n.SetPos(pos)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,14 @@ func (p *noder) funcLit(expr *syntax.FuncLit) *ir.Node {
|
||||||
ntype := p.typeExpr(expr.Type)
|
ntype := p.typeExpr(expr.Type)
|
||||||
|
|
||||||
dcl := p.nod(expr, ir.ODCLFUNC, nil, nil)
|
dcl := p.nod(expr, ir.ODCLFUNC, nil, nil)
|
||||||
fn := dcl.Func
|
fn := dcl.Func()
|
||||||
fn.SetIsHiddenClosure(Curfn != nil)
|
fn.SetIsHiddenClosure(Curfn != nil)
|
||||||
fn.Nname = newfuncnamel(p.pos(expr), ir.BlankNode.Sym, fn) // filled in by typecheckclosure
|
fn.Nname = newfuncnamel(p.pos(expr), ir.BlankNode.Sym(), fn) // filled in by typecheckclosure
|
||||||
fn.Nname.Name.Param.Ntype = xtype
|
fn.Nname.Name().Param.Ntype = xtype
|
||||||
fn.Nname.Name.Defn = dcl
|
fn.Nname.Name().Defn = dcl
|
||||||
|
|
||||||
clo := p.nod(expr, ir.OCLOSURE, nil, nil)
|
clo := p.nod(expr, ir.OCLOSURE, nil, nil)
|
||||||
clo.Func = fn
|
clo.SetFunc(fn)
|
||||||
fn.ClosureType = ntype
|
fn.ClosureType = ntype
|
||||||
fn.OClosure = clo
|
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.
|
// make the list of pointers for the closure call.
|
||||||
for _, v := range fn.ClosureVars.Slice() {
|
for _, v := range fn.ClosureVars.Slice() {
|
||||||
// Unlink from v1; see comment in syntax.go type Param for these fields.
|
// Unlink from v1; see comment in syntax.go type Param for these fields.
|
||||||
v1 := v.Name.Defn
|
v1 := v.Name().Defn
|
||||||
v1.Name.Param.Innermost = v.Name.Param.Outer
|
v1.Name().Param.Innermost = v.Name().Param.Outer
|
||||||
|
|
||||||
// If the closure usage of v is not dense,
|
// If the closure usage of v is not dense,
|
||||||
// we need to make it dense; now that we're out
|
// 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).
|
// obtains f3's v, creating it if necessary (as it is in the example).
|
||||||
//
|
//
|
||||||
// capturevars will decide whether to use v directly or &v.
|
// 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
|
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
|
// TODO: This creation of the named function should probably really be done in a
|
||||||
// separate pass from type-checking.
|
// separate pass from type-checking.
|
||||||
func typecheckclosure(clo *ir.Node, top int) {
|
func typecheckclosure(clo *ir.Node, top int) {
|
||||||
fn := clo.Func
|
fn := clo.Func()
|
||||||
dcl := fn.Decl
|
dcl := fn.Decl
|
||||||
// Set current associated iota value, so iota can be used inside
|
// Set current associated iota value, so iota can be used inside
|
||||||
// function in ConstSpec, see issue #22344
|
// function in ConstSpec, see issue #22344
|
||||||
|
|
@ -88,7 +88,7 @@ func typecheckclosure(clo *ir.Node, top int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn.ClosureType = typecheck(fn.ClosureType, ctxType)
|
fn.ClosureType = typecheck(fn.ClosureType, ctxType)
|
||||||
clo.Type = fn.ClosureType.Type
|
clo.SetType(fn.ClosureType.Type())
|
||||||
fn.ClosureCalled = top&ctxCallee != 0
|
fn.ClosureCalled = top&ctxCallee != 0
|
||||||
|
|
||||||
// Do not typecheck dcl twice, otherwise, we will end up pushing
|
// 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() {
|
for _, ln := range fn.ClosureVars.Slice() {
|
||||||
n := ln.Name.Defn
|
n := ln.Name().Defn
|
||||||
if !n.Name.Captured() {
|
if !n.Name().Captured() {
|
||||||
n.Name.SetCaptured(true)
|
n.Name().SetCaptured(true)
|
||||||
if n.Name.Decldepth == 0 {
|
if n.Name().Decldepth == 0 {
|
||||||
base.Fatalf("typecheckclosure: var %S does not have decldepth assigned", n)
|
base.Fatalf("typecheckclosure: var %S does not have decldepth assigned", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore assignments to the variable in straightline code
|
// Ignore assignments to the variable in straightline code
|
||||||
// preceding the first capturing by a closure.
|
// preceding the first capturing by a closure.
|
||||||
if n.Name.Decldepth == decldepth {
|
if n.Name().Decldepth == decldepth {
|
||||||
n.Name.SetAssigned(false)
|
n.Name().SetAssigned(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn.Nname.Sym = closurename(Curfn)
|
fn.Nname.SetSym(closurename(Curfn))
|
||||||
setNodeNameFunc(fn.Nname)
|
setNodeNameFunc(fn.Nname)
|
||||||
dcl = typecheck(dcl, ctxStmt)
|
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
|
// 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
|
// ready to type check code yet; we'll check it later, because the
|
||||||
// underlying closure function we create is added to xtop.
|
// underlying closure function we create is added to xtop.
|
||||||
if Curfn != nil && clo.Type != nil {
|
if Curfn != nil && clo.Type() != nil {
|
||||||
oldfn := Curfn
|
oldfn := Curfn
|
||||||
Curfn = dcl
|
Curfn = dcl
|
||||||
olddd := decldepth
|
olddd := decldepth
|
||||||
decldepth = 1
|
decldepth = 1
|
||||||
typecheckslice(dcl.Nbody.Slice(), ctxStmt)
|
typecheckslice(dcl.Body().Slice(), ctxStmt)
|
||||||
decldepth = olddd
|
decldepth = olddd
|
||||||
Curfn = oldfn
|
Curfn = oldfn
|
||||||
}
|
}
|
||||||
|
|
@ -146,7 +146,7 @@ func closurename(outerfunc *ir.Node) *types.Sym {
|
||||||
gen := &globClosgen
|
gen := &globClosgen
|
||||||
|
|
||||||
if outerfunc != nil {
|
if outerfunc != nil {
|
||||||
if outerfunc.Func.OClosure != nil {
|
if outerfunc.Func().OClosure != nil {
|
||||||
prefix = ""
|
prefix = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,8 +155,8 @@ func closurename(outerfunc *ir.Node) *types.Sym {
|
||||||
// There may be multiple functions named "_". In those
|
// There may be multiple functions named "_". In those
|
||||||
// cases, we can't use their individual Closgens as it
|
// cases, we can't use their individual Closgens as it
|
||||||
// would lead to name clashes.
|
// would lead to name clashes.
|
||||||
if !ir.IsBlank(outerfunc.Func.Nname) {
|
if !ir.IsBlank(outerfunc.Func().Nname) {
|
||||||
gen = &outerfunc.Func.Closgen
|
gen = &outerfunc.Func().Closgen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,12 +174,12 @@ var capturevarscomplete bool
|
||||||
// after capturing (effectively constant).
|
// after capturing (effectively constant).
|
||||||
func capturevars(dcl *ir.Node) {
|
func capturevars(dcl *ir.Node) {
|
||||||
lno := base.Pos
|
lno := base.Pos
|
||||||
base.Pos = dcl.Pos
|
base.Pos = dcl.Pos()
|
||||||
fn := dcl.Func
|
fn := dcl.Func()
|
||||||
cvars := fn.ClosureVars.Slice()
|
cvars := fn.ClosureVars.Slice()
|
||||||
out := cvars[:0]
|
out := cvars[:0]
|
||||||
for _, v := range cvars {
|
for _, v := range cvars {
|
||||||
if v.Type == nil {
|
if v.Type() == nil {
|
||||||
// If v.Type is nil, it means v looked like it
|
// If v.Type is nil, it means v looked like it
|
||||||
// was going to be used in the closure, but
|
// was going to be used in the closure, but
|
||||||
// isn't. This happens in struct literals like
|
// 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,
|
// type check the & of closed variables outside the closure,
|
||||||
// so that the outer frame also grabs them and knows they escape.
|
// so that the outer frame also grabs them and knows they escape.
|
||||||
dowidth(v.Type)
|
dowidth(v.Type())
|
||||||
|
|
||||||
outer := v.Name.Param.Outer
|
outer := v.Name().Param.Outer
|
||||||
outermost := v.Name.Defn
|
outermost := v.Name().Defn
|
||||||
|
|
||||||
// out parameters will be assigned to implicitly upon return.
|
// out parameters will be assigned to implicitly upon return.
|
||||||
if outermost.Class() != ir.PPARAMOUT && !outermost.Name.Addrtaken() && !outermost.Name.Assigned() && v.Type.Width <= 128 {
|
if outermost.Class() != ir.PPARAMOUT && !outermost.Name().Addrtaken() && !outermost.Name().Assigned() && v.Type().Width <= 128 {
|
||||||
v.Name.SetByval(true)
|
v.Name().SetByval(true)
|
||||||
} else {
|
} else {
|
||||||
outermost.Name.SetAddrtaken(true)
|
outermost.Name().SetAddrtaken(true)
|
||||||
outer = ir.Nod(ir.OADDR, outer, nil)
|
outer = ir.Nod(ir.OADDR, outer, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if base.Flag.LowerM > 1 {
|
if base.Flag.LowerM > 1 {
|
||||||
var name *types.Sym
|
var name *types.Sym
|
||||||
if v.Name.Curfn != nil && v.Name.Curfn.Func.Nname != nil {
|
if v.Name().Curfn != nil && v.Name().Curfn.Func().Nname != nil {
|
||||||
name = v.Name.Curfn.Func.Nname.Sym
|
name = v.Name().Curfn.Func().Nname.Sym()
|
||||||
}
|
}
|
||||||
how := "ref"
|
how := "ref"
|
||||||
if v.Name.Byval() {
|
if v.Name().Byval() {
|
||||||
how = "value"
|
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)
|
outer = typecheck(outer, ctxExpr)
|
||||||
|
|
@ -229,8 +229,8 @@ func capturevars(dcl *ir.Node) {
|
||||||
// It transform closure bodies to properly reference captured variables.
|
// It transform closure bodies to properly reference captured variables.
|
||||||
func transformclosure(dcl *ir.Node) {
|
func transformclosure(dcl *ir.Node) {
|
||||||
lno := base.Pos
|
lno := base.Pos
|
||||||
base.Pos = dcl.Pos
|
base.Pos = dcl.Pos()
|
||||||
fn := dcl.Func
|
fn := dcl.Func()
|
||||||
|
|
||||||
if fn.ClosureCalled {
|
if fn.ClosureCalled {
|
||||||
// If the closure is directly called, we transform it to a plain function call
|
// 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 params []*types.Field
|
||||||
var decls []*ir.Node
|
var decls []*ir.Node
|
||||||
for _, v := range fn.ClosureVars.Slice() {
|
for _, v := range fn.ClosureVars.Slice() {
|
||||||
if !v.Name.Byval() {
|
if !v.Name().Byval() {
|
||||||
// If v of type T is captured by reference,
|
// If v of type T is captured by reference,
|
||||||
// we introduce function param &v *T
|
// we introduce function param &v *T
|
||||||
// and v remains PAUTOHEAP with &v heapaddr
|
// and v remains PAUTOHEAP with &v heapaddr
|
||||||
// (accesses will implicitly deref &v).
|
// (accesses will implicitly deref &v).
|
||||||
addr := NewName(lookup("&" + v.Sym.Name))
|
addr := NewName(lookup("&" + v.Sym().Name))
|
||||||
addr.Type = types.NewPtr(v.Type)
|
addr.SetType(types.NewPtr(v.Type()))
|
||||||
v.Name.Param.Heapaddr = addr
|
v.Name().Param.Heapaddr = addr
|
||||||
v = addr
|
v = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
v.SetClass(ir.PPARAM)
|
v.SetClass(ir.PPARAM)
|
||||||
decls = append(decls, v)
|
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)
|
fld.Nname = ir.AsTypesNode(v)
|
||||||
params = append(params, fld)
|
params = append(params, fld)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(params) > 0 {
|
if len(params) > 0 {
|
||||||
// Prepend params and decls.
|
// 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...)
|
fn.Dcl = append(decls, fn.Dcl...)
|
||||||
}
|
}
|
||||||
|
|
||||||
dowidth(f.Type)
|
dowidth(f.Type())
|
||||||
dcl.Type = f.Type // update type of ODCLFUNC
|
dcl.SetType(f.Type()) // update type of ODCLFUNC
|
||||||
} else {
|
} else {
|
||||||
// The closure is not called, so it is going to stay as closure.
|
// The closure is not called, so it is going to stay as closure.
|
||||||
var body []*ir.Node
|
var body []*ir.Node
|
||||||
|
|
@ -290,15 +290,15 @@ func transformclosure(dcl *ir.Node) {
|
||||||
// cv refers to the field inside of closure OSTRUCTLIT.
|
// cv refers to the field inside of closure OSTRUCTLIT.
|
||||||
cv := ir.Nod(ir.OCLOSUREVAR, nil, nil)
|
cv := ir.Nod(ir.OCLOSUREVAR, nil, nil)
|
||||||
|
|
||||||
cv.Type = v.Type
|
cv.SetType(v.Type())
|
||||||
if !v.Name.Byval() {
|
if !v.Name().Byval() {
|
||||||
cv.Type = types.NewPtr(v.Type)
|
cv.SetType(types.NewPtr(v.Type()))
|
||||||
}
|
}
|
||||||
offset = Rnd(offset, int64(cv.Type.Align))
|
offset = Rnd(offset, int64(cv.Type().Align))
|
||||||
cv.Xoffset = offset
|
cv.SetOffset(offset)
|
||||||
offset += cv.Type.Width
|
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.
|
// If it is a small variable captured by value, downgrade it to PAUTO.
|
||||||
v.SetClass(ir.PAUTO)
|
v.SetClass(ir.PAUTO)
|
||||||
fn.Dcl = append(fn.Dcl, v)
|
fn.Dcl = append(fn.Dcl, v)
|
||||||
|
|
@ -306,14 +306,14 @@ func transformclosure(dcl *ir.Node) {
|
||||||
} else {
|
} else {
|
||||||
// Declare variable holding addresses taken from closure
|
// Declare variable holding addresses taken from closure
|
||||||
// and initialize in entry prologue.
|
// and initialize in entry prologue.
|
||||||
addr := NewName(lookup("&" + v.Sym.Name))
|
addr := NewName(lookup("&" + v.Sym().Name))
|
||||||
addr.Type = types.NewPtr(v.Type)
|
addr.SetType(types.NewPtr(v.Type()))
|
||||||
addr.SetClass(ir.PAUTO)
|
addr.SetClass(ir.PAUTO)
|
||||||
addr.Name.SetUsed(true)
|
addr.Name().SetUsed(true)
|
||||||
addr.Name.Curfn = dcl
|
addr.Name().Curfn = dcl
|
||||||
fn.Dcl = append(fn.Dcl, addr)
|
fn.Dcl = append(fn.Dcl, addr)
|
||||||
v.Name.Param.Heapaddr = addr
|
v.Name().Param.Heapaddr = addr
|
||||||
if v.Name.Byval() {
|
if v.Name().Byval() {
|
||||||
cv = ir.Nod(ir.OADDR, cv, nil)
|
cv = ir.Nod(ir.OADDR, cv, nil)
|
||||||
}
|
}
|
||||||
body = append(body, ir.Nod(ir.OAS, addr, cv))
|
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
|
// hasemptycvars reports whether closure clo has an
|
||||||
// empty list of captured vars.
|
// empty list of captured vars.
|
||||||
func hasemptycvars(clo *ir.Node) bool {
|
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
|
// closuredebugruntimecheck applies boilerplate checks for debug flags
|
||||||
// and compiling runtime
|
// and compiling runtime
|
||||||
func closuredebugruntimecheck(clo *ir.Node) {
|
func closuredebugruntimecheck(clo *ir.Node) {
|
||||||
if base.Debug.Closure > 0 {
|
if base.Debug.Closure > 0 {
|
||||||
if clo.Esc == EscHeap {
|
if clo.Esc() == EscHeap {
|
||||||
base.WarnfAt(clo.Pos, "heap closure, captured vars = %v", clo.Func.ClosureVars)
|
base.WarnfAt(clo.Pos(), "heap closure, captured vars = %v", clo.Func().ClosureVars)
|
||||||
} else {
|
} 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 {
|
if base.Flag.CompilingRuntime && clo.Esc() == EscHeap {
|
||||||
base.ErrorfAt(clo.Pos, "heap-allocated closure, not allowed in runtime")
|
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{
|
fields := []*ir.Node{
|
||||||
namedfield(".F", types.Types[types.TUINTPTR]),
|
namedfield(".F", types.Types[types.TUINTPTR]),
|
||||||
}
|
}
|
||||||
for _, v := range clo.Func.ClosureVars.Slice() {
|
for _, v := range clo.Func().ClosureVars.Slice() {
|
||||||
typ := v.Type
|
typ := v.Type()
|
||||||
if !v.Name.Byval() {
|
if !v.Name().Byval() {
|
||||||
typ = types.NewPtr(typ)
|
typ = types.NewPtr(typ)
|
||||||
}
|
}
|
||||||
fields = append(fields, symfield(v.Sym, typ))
|
fields = append(fields, symfield(v.Sym(), typ))
|
||||||
}
|
}
|
||||||
typ := tostruct(fields)
|
typ := tostruct(fields)
|
||||||
typ.SetNoalg(true)
|
typ.SetNoalg(true)
|
||||||
|
|
@ -384,12 +384,12 @@ func closureType(clo *ir.Node) *types.Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
func walkclosure(clo *ir.Node, init *ir.Nodes) *ir.Node {
|
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 no closure vars, don't bother wrapping.
|
||||||
if hasemptycvars(clo) {
|
if hasemptycvars(clo) {
|
||||||
if base.Debug.Closure > 0 {
|
if base.Debug.Closure > 0 {
|
||||||
base.WarnfAt(clo.Pos, "closure converted to global")
|
base.WarnfAt(clo.Pos(), "closure converted to global")
|
||||||
}
|
}
|
||||||
return fn.Nname
|
return fn.Nname
|
||||||
}
|
}
|
||||||
|
|
@ -398,21 +398,21 @@ func walkclosure(clo *ir.Node, init *ir.Nodes) *ir.Node {
|
||||||
typ := closureType(clo)
|
typ := closureType(clo)
|
||||||
|
|
||||||
clos := ir.Nod(ir.OCOMPLIT, nil, typenod(typ))
|
clos := ir.Nod(ir.OCOMPLIT, nil, typenod(typ))
|
||||||
clos.Esc = clo.Esc
|
clos.SetEsc(clo.Esc())
|
||||||
clos.List.Set(append([]*ir.Node{ir.Nod(ir.OCFUNC, fn.Nname, nil)}, fn.ClosureEnter.Slice()...))
|
clos.PtrList().Set(append([]*ir.Node{ir.Nod(ir.OCFUNC, fn.Nname, nil)}, fn.ClosureEnter.Slice()...))
|
||||||
|
|
||||||
clos = ir.Nod(ir.OADDR, clos, nil)
|
clos = ir.Nod(ir.OADDR, clos, nil)
|
||||||
clos.Esc = clo.Esc
|
clos.SetEsc(clo.Esc())
|
||||||
|
|
||||||
// Force type conversion from *struct to the func type.
|
// 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.
|
// non-escaping temp to use, if any.
|
||||||
if x := prealloc[clo]; x != nil {
|
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")
|
panic("closure type does not match order's assigned type")
|
||||||
}
|
}
|
||||||
clos.Left.Right = x
|
clos.Left().SetRight(x)
|
||||||
delete(prealloc, clo)
|
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) {
|
func typecheckpartialcall(dot *ir.Node, sym *types.Sym) {
|
||||||
switch dot.Op {
|
switch dot.Op() {
|
||||||
case ir.ODOTINTER, ir.ODOTMETH:
|
case ir.ODOTINTER, ir.ODOTMETH:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
@ -429,19 +429,19 @@ func typecheckpartialcall(dot *ir.Node, sym *types.Sym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create top-level function.
|
// Create top-level function.
|
||||||
dcl := makepartialcall(dot, dot.Type, sym)
|
dcl := makepartialcall(dot, dot.Type(), sym)
|
||||||
dcl.Func.SetWrapper(true)
|
dcl.Func().SetWrapper(true)
|
||||||
dot.Op = ir.OCALLPART
|
dot.SetOp(ir.OCALLPART)
|
||||||
dot.Right = NewName(sym)
|
dot.SetRight(NewName(sym))
|
||||||
dot.Type = dcl.Type
|
dot.SetType(dcl.Type())
|
||||||
dot.Func = dcl.Func
|
dot.SetFunc(dcl.Func())
|
||||||
dot.SetOpt(nil) // clear types.Field from ODOTMETH
|
dot.SetOpt(nil) // clear types.Field from ODOTMETH
|
||||||
}
|
}
|
||||||
|
|
||||||
// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
|
// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
|
||||||
// for partial calls.
|
// for partial calls.
|
||||||
func makepartialcall(dot *ir.Node, t0 *types.Type, meth *types.Sym) *ir.Node {
|
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")
|
sym := methodSymSuffix(rcvrtype, meth, "-fm")
|
||||||
|
|
||||||
if sym.Uniq() {
|
if sym.Uniq() {
|
||||||
|
|
@ -465,52 +465,52 @@ func makepartialcall(dot *ir.Node, t0 *types.Type, meth *types.Sym) *ir.Node {
|
||||||
// case. See issue 29389.
|
// case. See issue 29389.
|
||||||
|
|
||||||
tfn := ir.Nod(ir.OTFUNC, nil, nil)
|
tfn := ir.Nod(ir.OTFUNC, nil, nil)
|
||||||
tfn.List.Set(structargs(t0.Params(), true))
|
tfn.PtrList().Set(structargs(t0.Params(), true))
|
||||||
tfn.Rlist.Set(structargs(t0.Results(), false))
|
tfn.PtrRlist().Set(structargs(t0.Results(), false))
|
||||||
|
|
||||||
dcl := dclfunc(sym, tfn)
|
dcl := dclfunc(sym, tfn)
|
||||||
fn := dcl.Func
|
fn := dcl.Func()
|
||||||
fn.SetDupok(true)
|
fn.SetDupok(true)
|
||||||
fn.SetNeedctxt(true)
|
fn.SetNeedctxt(true)
|
||||||
|
|
||||||
tfn.Type.SetPkg(t0.Pkg())
|
tfn.Type().SetPkg(t0.Pkg())
|
||||||
|
|
||||||
// Declare and initialize variable holding receiver.
|
// Declare and initialize variable holding receiver.
|
||||||
|
|
||||||
cv := ir.Nod(ir.OCLOSUREVAR, nil, nil)
|
cv := ir.Nod(ir.OCLOSUREVAR, nil, nil)
|
||||||
cv.Type = rcvrtype
|
cv.SetType(rcvrtype)
|
||||||
cv.Xoffset = Rnd(int64(Widthptr), int64(cv.Type.Align))
|
cv.SetOffset(Rnd(int64(Widthptr), int64(cv.Type().Align)))
|
||||||
|
|
||||||
ptr := NewName(lookup(".this"))
|
ptr := NewName(lookup(".this"))
|
||||||
declare(ptr, ir.PAUTO)
|
declare(ptr, ir.PAUTO)
|
||||||
ptr.Name.SetUsed(true)
|
ptr.Name().SetUsed(true)
|
||||||
var body []*ir.Node
|
var body []*ir.Node
|
||||||
if rcvrtype.IsPtr() || rcvrtype.IsInterface() {
|
if rcvrtype.IsPtr() || rcvrtype.IsInterface() {
|
||||||
ptr.Type = rcvrtype
|
ptr.SetType(rcvrtype)
|
||||||
body = append(body, ir.Nod(ir.OAS, ptr, cv))
|
body = append(body, ir.Nod(ir.OAS, ptr, cv))
|
||||||
} else {
|
} 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)))
|
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 := ir.Nod(ir.OCALL, nodSym(ir.OXDOT, ptr, meth), nil)
|
||||||
call.List.Set(paramNnames(tfn.Type))
|
call.PtrList().Set(paramNnames(tfn.Type()))
|
||||||
call.SetIsDDD(tfn.Type.IsVariadic())
|
call.SetIsDDD(tfn.Type().IsVariadic())
|
||||||
if t0.NumResults() != 0 {
|
if t0.NumResults() != 0 {
|
||||||
n := ir.Nod(ir.ORETURN, nil, nil)
|
n := ir.Nod(ir.ORETURN, nil, nil)
|
||||||
n.List.Set1(call)
|
n.PtrList().Set1(call)
|
||||||
call = n
|
call = n
|
||||||
}
|
}
|
||||||
body = append(body, call)
|
body = append(body, call)
|
||||||
|
|
||||||
dcl.Nbody.Set(body)
|
dcl.PtrBody().Set(body)
|
||||||
funcbody()
|
funcbody()
|
||||||
|
|
||||||
dcl = typecheck(dcl, ctxStmt)
|
dcl = typecheck(dcl, ctxStmt)
|
||||||
// Need to typecheck the body of the just-generated wrapper.
|
// Need to typecheck the body of the just-generated wrapper.
|
||||||
// typecheckslice() requires that Curfn is set when processing an ORETURN.
|
// typecheckslice() requires that Curfn is set when processing an ORETURN.
|
||||||
Curfn = dcl
|
Curfn = dcl
|
||||||
typecheckslice(dcl.Nbody.Slice(), ctxStmt)
|
typecheckslice(dcl.Body().Slice(), ctxStmt)
|
||||||
sym.Def = ir.AsTypesNode(dcl)
|
sym.Def = ir.AsTypesNode(dcl)
|
||||||
xtop = append(xtop, dcl)
|
xtop = append(xtop, dcl)
|
||||||
Curfn = savecurfn
|
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 {
|
func partialCallType(n *ir.Node) *types.Type {
|
||||||
t := tostruct([]*ir.Node{
|
t := tostruct([]*ir.Node{
|
||||||
namedfield("F", types.Types[types.TUINTPTR]),
|
namedfield("F", types.Types[types.TUINTPTR]),
|
||||||
namedfield("R", n.Left.Type),
|
namedfield("R", n.Left().Type()),
|
||||||
})
|
})
|
||||||
t.SetNoalg(true)
|
t.SetNoalg(true)
|
||||||
return t
|
return t
|
||||||
|
|
@ -539,13 +539,13 @@ func walkpartialcall(n *ir.Node, init *ir.Nodes) *ir.Node {
|
||||||
//
|
//
|
||||||
// Like walkclosure above.
|
// Like walkclosure above.
|
||||||
|
|
||||||
if n.Left.Type.IsInterface() {
|
if n.Left().Type().IsInterface() {
|
||||||
// Trigger panic for method on nil interface now.
|
// Trigger panic for method on nil interface now.
|
||||||
// Otherwise it happens in the wrapper and is confusing.
|
// Otherwise it happens in the wrapper and is confusing.
|
||||||
n.Left = cheapexpr(n.Left, init)
|
n.SetLeft(cheapexpr(n.Left(), init))
|
||||||
n.Left = walkexpr(n.Left, nil)
|
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)
|
tab = typecheck(tab, ctxExpr)
|
||||||
|
|
||||||
c := ir.Nod(ir.OCHECKNIL, tab, nil)
|
c := ir.Nod(ir.OCHECKNIL, tab, nil)
|
||||||
|
|
@ -556,21 +556,21 @@ func walkpartialcall(n *ir.Node, init *ir.Nodes) *ir.Node {
|
||||||
typ := partialCallType(n)
|
typ := partialCallType(n)
|
||||||
|
|
||||||
clos := ir.Nod(ir.OCOMPLIT, nil, typenod(typ))
|
clos := ir.Nod(ir.OCOMPLIT, nil, typenod(typ))
|
||||||
clos.Esc = n.Esc
|
clos.SetEsc(n.Esc())
|
||||||
clos.List.Set2(ir.Nod(ir.OCFUNC, n.Func.Nname, nil), n.Left)
|
clos.PtrList().Set2(ir.Nod(ir.OCFUNC, n.Func().Nname, nil), n.Left())
|
||||||
|
|
||||||
clos = ir.Nod(ir.OADDR, clos, nil)
|
clos = ir.Nod(ir.OADDR, clos, nil)
|
||||||
clos.Esc = n.Esc
|
clos.SetEsc(n.Esc())
|
||||||
|
|
||||||
// Force type conversion from *struct to the func type.
|
// 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.
|
// non-escaping temp to use, if any.
|
||||||
if x := prealloc[n]; x != nil {
|
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")
|
panic("partial call type does not match order's assigned type")
|
||||||
}
|
}
|
||||||
clos.Left.Right = x
|
clos.Left().SetRight(x)
|
||||||
delete(prealloc, n)
|
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
|
// callpartMethod returns the *types.Field representing the method
|
||||||
// referenced by method value n.
|
// referenced by method value n.
|
||||||
func callpartMethod(n *ir.Node) *types.Field {
|
func callpartMethod(n *ir.Node) *types.Field {
|
||||||
if n.Op != ir.OCALLPART {
|
if n.Op() != ir.OCALLPART {
|
||||||
base.Fatalf("expected OCALLPART, got %v", n)
|
base.Fatalf("expected OCALLPART, got %v", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(mdempsky): Optimize this. If necessary,
|
// TODO(mdempsky): Optimize this. If necessary,
|
||||||
// makepartialcall could save m for us somewhere.
|
// makepartialcall could save m for us somewhere.
|
||||||
var m *types.Field
|
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")
|
base.Fatalf("failed to find field for OCALLPART")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
base.Fatalf("bad conversion to untyped: %v", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n == nil || n.Type == nil {
|
if n == nil || n.Type() == nil {
|
||||||
// Allow sloppy callers.
|
// Allow sloppy callers.
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
if !n.Type.IsUntyped() {
|
if !n.Type().IsUntyped() {
|
||||||
// Already typed; nothing to do.
|
// Already typed; nothing to do.
|
||||||
return n
|
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.
|
// Can't always set n.Type directly on OLITERAL nodes.
|
||||||
// See discussion on CL 20813.
|
// See discussion on CL 20813.
|
||||||
n = n.RawCopy()
|
n = n.RawCopy()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nil is technically not a constant, so handle it specially.
|
// Nil is technically not a constant, so handle it specially.
|
||||||
if n.Type.Etype == types.TNIL {
|
if n.Type().Etype == types.TNIL {
|
||||||
if n.Op != ir.ONIL {
|
if n.Op() != ir.ONIL {
|
||||||
base.Fatalf("unexpected op: %v (%v)", n, n.Op)
|
base.Fatalf("unexpected op: %v (%v)", n, n.Op())
|
||||||
}
|
}
|
||||||
if t == nil {
|
if t == nil {
|
||||||
base.Errorf("use of untyped nil")
|
base.Errorf("use of untyped nil")
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
n.Type = nil
|
n.SetType(nil)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,15 +138,15 @@ func convlit1(n *ir.Node, t *types.Type, explicit bool, context func() string) *
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Type = t
|
n.SetType(t)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
if t == nil || !ir.OKForConst[t.Etype] {
|
if t == nil || !ir.OKForConst[t.Etype] {
|
||||||
t = defaultType(n.Type)
|
t = defaultType(n.Type())
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
default:
|
default:
|
||||||
base.Fatalf("unexpected untyped expression: %v", n)
|
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 {
|
if v.Kind() == constant.Unknown {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
n.Type = t
|
n.SetType(t)
|
||||||
n.SetVal(v)
|
n.SetVal(v)
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.OREAL, ir.OIMAG:
|
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 {
|
if ot == nil {
|
||||||
n = defaultlit(n, nil)
|
n = defaultlit(n, nil)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Left = convlit(n.Left, ot)
|
n.SetLeft(convlit(n.Left(), ot))
|
||||||
if n.Left.Type == nil {
|
if n.Left().Type() == nil {
|
||||||
n.Type = nil
|
n.SetType(nil)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
n.Type = t
|
n.SetType(t)
|
||||||
return n
|
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:
|
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 {
|
if ot == nil {
|
||||||
n = defaultlit(n, nil)
|
n = defaultlit(n, nil)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Left = convlit(n.Left, ot)
|
n.SetLeft(convlit(n.Left(), ot))
|
||||||
n.Right = convlit(n.Right, ot)
|
n.SetRight(convlit(n.Right(), ot))
|
||||||
if n.Left.Type == nil || n.Right.Type == nil {
|
if n.Left().Type() == nil || n.Right().Type() == nil {
|
||||||
n.Type = nil
|
n.SetType(nil)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
if !types.Identical(n.Left.Type, n.Right.Type) {
|
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)
|
base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, n.Left().Type(), n.Right().Type())
|
||||||
n.Type = nil
|
n.SetType(nil)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Type = t
|
n.SetType(t)
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
|
case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
|
||||||
if !t.IsBoolean() {
|
if !t.IsBoolean() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
n.Type = t
|
n.SetType(t)
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.OLSH, ir.ORSH:
|
case ir.OLSH, ir.ORSH:
|
||||||
n.Left = convlit1(n.Left, t, explicit, nil)
|
n.SetLeft(convlit1(n.Left(), t, explicit, nil))
|
||||||
n.Type = n.Left.Type
|
n.SetType(n.Left().Type())
|
||||||
if n.Type != nil && !n.Type.IsInteger() {
|
if n.Type() != nil && !n.Type().IsInteger() {
|
||||||
base.Errorf("invalid operation: %v (shift of type %v)", n, n.Type)
|
base.Errorf("invalid operation: %v (shift of type %v)", n, n.Type())
|
||||||
n.Type = nil
|
n.SetType(nil)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -225,7 +225,7 @@ func convlit1(n *ir.Node, t *types.Type, explicit bool, context func() string) *
|
||||||
}
|
}
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
}
|
}
|
||||||
n.Type = nil
|
n.SetType(nil)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -439,75 +439,75 @@ var tokenForOp = [...]token.Token{
|
||||||
// Otherwise, evalConst returns a new OLITERAL with the same value as n,
|
// Otherwise, evalConst returns a new OLITERAL with the same value as n,
|
||||||
// and with .Orig pointing back to n.
|
// and with .Orig pointing back to n.
|
||||||
func evalConst(n *ir.Node) *ir.Node {
|
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.
|
// 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:
|
case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT:
|
||||||
if nl.Op == ir.OLITERAL {
|
if nl.Op() == ir.OLITERAL {
|
||||||
var prec uint
|
var prec uint
|
||||||
if n.Type.IsUnsigned() {
|
if n.Type().IsUnsigned() {
|
||||||
prec = uint(n.Type.Size() * 8)
|
prec = uint(n.Type().Size() * 8)
|
||||||
}
|
}
|
||||||
return origConst(n, constant.UnaryOp(tokenForOp[op], nl.Val(), prec))
|
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:
|
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()
|
rval := nr.Val()
|
||||||
|
|
||||||
// check for divisor underflow in complex division (see issue 20227)
|
// 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")
|
base.Errorf("complex division by zero")
|
||||||
n.Type = nil
|
n.SetType(nil)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
if (op == ir.ODIV || op == ir.OMOD) && constant.Sign(rval) == 0 {
|
if (op == ir.ODIV || op == ir.OMOD) && constant.Sign(rval) == 0 {
|
||||||
base.Errorf("division by zero")
|
base.Errorf("division by zero")
|
||||||
n.Type = nil
|
n.SetType(nil)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
tok := tokenForOp[op]
|
tok := tokenForOp[op]
|
||||||
if op == ir.ODIV && n.Type.IsInteger() {
|
if op == ir.ODIV && n.Type().IsInteger() {
|
||||||
tok = token.QUO_ASSIGN // integer division
|
tok = token.QUO_ASSIGN // integer division
|
||||||
}
|
}
|
||||||
return origConst(n, constant.BinaryOp(nl.Val(), tok, rval))
|
return origConst(n, constant.BinaryOp(nl.Val(), tok, rval))
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
|
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()))
|
return origBoolConst(n, constant.Compare(nl.Val(), tokenForOp[op], nr.Val()))
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OLSH, ir.ORSH:
|
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"
|
// shiftBound from go/types; "so we can express smallestFloat64"
|
||||||
const shiftBound = 1023 - 1 + 52
|
const shiftBound = 1023 - 1 + 52
|
||||||
s, ok := constant.Uint64Val(nr.Val())
|
s, ok := constant.Uint64Val(nr.Val())
|
||||||
if !ok || s > shiftBound {
|
if !ok || s > shiftBound {
|
||||||
base.Errorf("invalid shift count %v", nr)
|
base.Errorf("invalid shift count %v", nr)
|
||||||
n.Type = nil
|
n.SetType(nil)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return origConst(n, constant.Shift(toint(nl.Val()), tokenForOp[op], uint(s)))
|
return origConst(n, constant.Shift(toint(nl.Val()), tokenForOp[op], uint(s)))
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OCONV, ir.ORUNESTR:
|
case ir.OCONV, ir.ORUNESTR:
|
||||||
if ir.OKForConst[n.Type.Etype] && nl.Op == ir.OLITERAL {
|
if ir.OKForConst[n.Type().Etype] && nl.Op() == ir.OLITERAL {
|
||||||
return origConst(n, convertVal(nl.Val(), n.Type, true))
|
return origConst(n, convertVal(nl.Val(), n.Type(), true))
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OCONVNOP:
|
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
|
// set so n.Orig gets OCONV instead of OCONVNOP
|
||||||
n.Op = ir.OCONV
|
n.SetOp(ir.OCONV)
|
||||||
return origConst(n, nl.Val())
|
return origConst(n, nl.Val())
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OADDSTR:
|
case ir.OADDSTR:
|
||||||
// Merge adjacent constants in the argument list.
|
// Merge adjacent constants in the argument list.
|
||||||
s := n.List.Slice()
|
s := n.List().Slice()
|
||||||
need := 0
|
need := 0
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
if i == 0 || !ir.IsConst(s[i-1], constant.String) || !ir.IsConst(s[i], constant.String) {
|
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 := 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)
|
newList = append(newList, nl)
|
||||||
i = i2 - 1
|
i = i2 - 1
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -546,18 +546,18 @@ func evalConst(n *ir.Node) *ir.Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
n = ir.Copy(n)
|
n = ir.Copy(n)
|
||||||
n.List.Set(newList)
|
n.PtrList().Set(newList)
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.OCAP, ir.OLEN:
|
case ir.OCAP, ir.OLEN:
|
||||||
switch nl.Type.Etype {
|
switch nl.Type().Etype {
|
||||||
case types.TSTRING:
|
case types.TSTRING:
|
||||||
if ir.IsConst(nl, constant.String) {
|
if ir.IsConst(nl, constant.String) {
|
||||||
return origIntConst(n, int64(len(nl.StringVal())))
|
return origIntConst(n, int64(len(nl.StringVal())))
|
||||||
}
|
}
|
||||||
case types.TARRAY:
|
case types.TARRAY:
|
||||||
if !hascallchan(nl) {
|
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))
|
return origIntConst(n, evalunsafe(n))
|
||||||
|
|
||||||
case ir.OREAL:
|
case ir.OREAL:
|
||||||
if nl.Op == ir.OLITERAL {
|
if nl.Op() == ir.OLITERAL {
|
||||||
return origConst(n, constant.Real(nl.Val()))
|
return origConst(n, constant.Real(nl.Val()))
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OIMAG:
|
case ir.OIMAG:
|
||||||
if nl.Op == ir.OLITERAL {
|
if nl.Op() == ir.OLITERAL {
|
||||||
return origConst(n, constant.Imag(nl.Val()))
|
return origConst(n, constant.Imag(nl.Val()))
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OCOMPLEX:
|
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()))
|
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.
|
// origConst returns an OLITERAL with orig n and value v.
|
||||||
func origConst(n *ir.Node, v constant.Value) *ir.Node {
|
func origConst(n *ir.Node, v constant.Value) *ir.Node {
|
||||||
lno := setlineno(n)
|
lno := setlineno(n)
|
||||||
v = convertVal(v, n.Type, false)
|
v = convertVal(v, n.Type(), false)
|
||||||
base.Pos = lno
|
base.Pos = lno
|
||||||
|
|
||||||
switch v.Kind() {
|
switch v.Kind() {
|
||||||
|
|
@ -631,19 +631,19 @@ func origConst(n *ir.Node, v constant.Value) *ir.Node {
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case constant.Unknown:
|
case constant.Unknown:
|
||||||
what := overflowNames[n.Op]
|
what := overflowNames[n.Op()]
|
||||||
if what == "" {
|
if what == "" {
|
||||||
base.Fatalf("unexpected overflow: %v", n.Op)
|
base.Fatalf("unexpected overflow: %v", n.Op())
|
||||||
}
|
}
|
||||||
base.ErrorfAt(n.Pos, "constant %v overflow", what)
|
base.ErrorfAt(n.Pos(), "constant %v overflow", what)
|
||||||
n.Type = nil
|
n.SetType(nil)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
orig := n
|
orig := n
|
||||||
n = ir.NodAt(orig.Pos, ir.OLITERAL, nil, nil)
|
n = ir.NodAt(orig.Pos(), ir.OLITERAL, nil, nil)
|
||||||
n.Orig = orig
|
n.SetOrig(orig)
|
||||||
n.Type = orig.Type
|
n.SetType(orig.Type())
|
||||||
n.SetVal(v)
|
n.SetVal(v)
|
||||||
return n
|
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.
|
// The results of defaultlit2 MUST be assigned back to l and r, e.g.
|
||||||
// n.Left, n.Right = defaultlit2(n.Left, n.Right, force)
|
// n.Left, n.Right = defaultlit2(n.Left, n.Right, force)
|
||||||
func defaultlit2(l *ir.Node, r *ir.Node, force bool) (*ir.Node, *ir.Node) {
|
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
|
return l, r
|
||||||
}
|
}
|
||||||
if !l.Type.IsUntyped() {
|
if !l.Type().IsUntyped() {
|
||||||
r = convlit(r, l.Type)
|
r = convlit(r, l.Type())
|
||||||
return l, r
|
return l, r
|
||||||
}
|
}
|
||||||
|
|
||||||
if !r.Type.IsUntyped() {
|
if !r.Type().IsUntyped() {
|
||||||
l = convlit(l, r.Type)
|
l = convlit(l, r.Type())
|
||||||
return l, r
|
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).
|
// 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
|
return l, r
|
||||||
}
|
}
|
||||||
if l.Type.IsString() != r.Type.IsString() {
|
if l.Type().IsString() != r.Type().IsString() {
|
||||||
return l, r
|
return l, r
|
||||||
}
|
}
|
||||||
if ir.IsNil(l) || ir.IsNil(r) {
|
if ir.IsNil(l) || ir.IsNil(r) {
|
||||||
return l, r
|
return l, r
|
||||||
}
|
}
|
||||||
|
|
||||||
t := defaultType(mixUntyped(l.Type, r.Type))
|
t := defaultType(mixUntyped(l.Type(), r.Type()))
|
||||||
l = convlit(l, t)
|
l = convlit(l, t)
|
||||||
r = convlit(r, t)
|
r = convlit(r, t)
|
||||||
return l, r
|
return l, r
|
||||||
|
|
@ -748,7 +748,7 @@ func defaultType(t *types.Type) *types.Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
func smallintconst(n *ir.Node) bool {
|
func smallintconst(n *ir.Node) bool {
|
||||||
if n.Op == ir.OLITERAL {
|
if n.Op() == ir.OLITERAL {
|
||||||
v, ok := constant.Int64Val(n.Val())
|
v, ok := constant.Int64Val(n.Val())
|
||||||
return ok && int64(int32(v)) == v
|
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
|
// integer, or negative, it returns -1. If n is too large, it
|
||||||
// returns -2.
|
// returns -2.
|
||||||
func indexconst(n *ir.Node) int64 {
|
func indexconst(n *ir.Node) int64 {
|
||||||
if n.Op != ir.OLITERAL {
|
if n.Op() != ir.OLITERAL {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
if !n.Type.IsInteger() && n.Type.Etype != types.TIDEAL {
|
if !n.Type().IsInteger() && n.Type().Etype != types.TIDEAL {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -784,14 +784,14 @@ func indexconst(n *ir.Node) int64 {
|
||||||
// Expressions derived from nil, like string([]byte(nil)), while they
|
// Expressions derived from nil, like string([]byte(nil)), while they
|
||||||
// may be known at compile time, are not Go language constants.
|
// may be known at compile time, are not Go language constants.
|
||||||
func isGoConst(n *ir.Node) bool {
|
func isGoConst(n *ir.Node) bool {
|
||||||
return n.Op == ir.OLITERAL
|
return n.Op() == ir.OLITERAL
|
||||||
}
|
}
|
||||||
|
|
||||||
func hascallchan(n *ir.Node) bool {
|
func hascallchan(n *ir.Node) bool {
|
||||||
if n == nil {
|
if n == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.OAPPEND,
|
case ir.OAPPEND,
|
||||||
ir.OCALL,
|
ir.OCALL,
|
||||||
ir.OCALLFUNC,
|
ir.OCALLFUNC,
|
||||||
|
|
@ -815,15 +815,15 @@ func hascallchan(n *ir.Node) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if hascallchan(n.Left) || hascallchan(n.Right) {
|
if hascallchan(n.Left()) || hascallchan(n.Right()) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
for _, n1 := range n.List.Slice() {
|
for _, n1 := range n.List().Slice() {
|
||||||
if hascallchan(n1) {
|
if hascallchan(n1) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, n2 := range n.Rlist.Slice() {
|
for _, n2 := range n.Rlist().Slice() {
|
||||||
if hascallchan(n2) {
|
if hascallchan(n2) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -852,14 +852,14 @@ type constSetKey struct {
|
||||||
//
|
//
|
||||||
// n must not be an untyped constant.
|
// n must not be an untyped constant.
|
||||||
func (s *constSet) add(pos src.XPos, n *ir.Node, what, where string) {
|
func (s *constSet) add(pos src.XPos, n *ir.Node, what, where string) {
|
||||||
if n.Op == ir.OCONVIFACE && n.Implicit() {
|
if n.Op() == ir.OCONVIFACE && n.Implicit() {
|
||||||
n = n.Left
|
n = n.Left()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isGoConst(n) {
|
if !isGoConst(n) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Type.IsUntyped() {
|
if n.Type().IsUntyped() {
|
||||||
base.Fatalf("%v is untyped", n)
|
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
|
// #21866 by treating all type aliases like byte/uint8 and
|
||||||
// rune/int32.
|
// rune/int32.
|
||||||
|
|
||||||
typ := n.Type
|
typ := n.Type()
|
||||||
switch typ {
|
switch typ {
|
||||||
case types.Bytetype:
|
case types.Bytetype:
|
||||||
typ = types.Types[types.TUINT8]
|
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)}
|
k := constSetKey{typ, ir.ConstValue(n)}
|
||||||
|
|
||||||
if hasUniquePos(n) {
|
if hasUniquePos(n) {
|
||||||
pos = n.Pos
|
pos = n.Pos()
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.m == nil {
|
if s.m == nil {
|
||||||
|
|
|
||||||
|
|
@ -64,78 +64,78 @@ func declare(n *ir.Node, ctxt ir.Class) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Name == nil {
|
if n.Name() == nil {
|
||||||
// named OLITERAL needs Name; most OLITERALs don't.
|
// 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.
|
// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
|
||||||
if !inimport && !typecheckok && s.Pkg != ir.LocalPkg {
|
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
|
gen := 0
|
||||||
if ctxt == ir.PEXTERN {
|
if ctxt == ir.PEXTERN {
|
||||||
if s.Name == "init" {
|
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" {
|
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)
|
externdcl = append(externdcl, n)
|
||||||
} else {
|
} else {
|
||||||
if Curfn == nil && ctxt == ir.PAUTO {
|
if Curfn == nil && ctxt == ir.PAUTO {
|
||||||
base.Pos = n.Pos
|
base.Pos = n.Pos()
|
||||||
base.Fatalf("automatic outside function")
|
base.Fatalf("automatic outside function")
|
||||||
}
|
}
|
||||||
if Curfn != nil && ctxt != ir.PFUNC {
|
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++
|
declare_typegen++
|
||||||
gen = 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++
|
vargen++
|
||||||
gen = vargen
|
gen = vargen
|
||||||
}
|
}
|
||||||
types.Pushdcl(s)
|
types.Pushdcl(s)
|
||||||
n.Name.Curfn = Curfn
|
n.Name().Curfn = Curfn
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctxt == ir.PAUTO {
|
if ctxt == ir.PAUTO {
|
||||||
n.Xoffset = 0
|
n.SetOffset(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Block == types.Block {
|
if s.Block == types.Block {
|
||||||
// functype will print errors about duplicate function arguments.
|
// functype will print errors about duplicate function arguments.
|
||||||
// Don't repeat the error here.
|
// Don't repeat the error here.
|
||||||
if ctxt != ir.PPARAM && ctxt != ir.PPARAMOUT {
|
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.Block = types.Block
|
||||||
s.Lastlineno = base.Pos
|
s.Lastlineno = base.Pos
|
||||||
s.Def = ir.AsTypesNode(n)
|
s.Def = ir.AsTypesNode(n)
|
||||||
n.Name.Vargen = int32(gen)
|
n.Name().Vargen = int32(gen)
|
||||||
n.SetClass(ctxt)
|
n.SetClass(ctxt)
|
||||||
if ctxt == ir.PFUNC {
|
if ctxt == ir.PFUNC {
|
||||||
n.Sym.SetFunc(true)
|
n.Sym().SetFunc(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
autoexport(n, ctxt)
|
autoexport(n, ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func addvar(n *ir.Node, t *types.Type, ctxt ir.Class) {
|
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)
|
base.Fatalf("addvar: n=%v t=%v nil", n, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Op = ir.ONAME
|
n.SetOp(ir.ONAME)
|
||||||
declare(n, ctxt)
|
declare(n, ctxt)
|
||||||
n.Type = t
|
n.SetType(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// declare variables from grammar
|
// 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 {
|
if len(el) == 1 && len(vl) > 1 {
|
||||||
e := el[0]
|
e := el[0]
|
||||||
as2 := ir.Nod(ir.OAS2, nil, nil)
|
as2 := ir.Nod(ir.OAS2, nil, nil)
|
||||||
as2.List.Set(vl)
|
as2.PtrList().Set(vl)
|
||||||
as2.Rlist.Set1(e)
|
as2.PtrRlist().Set1(e)
|
||||||
for _, v := range vl {
|
for _, v := range vl {
|
||||||
v.Op = ir.ONAME
|
v.SetOp(ir.ONAME)
|
||||||
declare(v, dclcontext)
|
declare(v, dclcontext)
|
||||||
v.Name.Param.Ntype = t
|
v.Name().Param.Ntype = t
|
||||||
v.Name.Defn = as2
|
v.Name().Defn = as2
|
||||||
if Curfn != nil {
|
if Curfn != nil {
|
||||||
init = append(init, ir.Nod(ir.ODCL, v, 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:]
|
el = el[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
v.Op = ir.ONAME
|
v.SetOp(ir.ONAME)
|
||||||
declare(v, dclcontext)
|
declare(v, dclcontext)
|
||||||
v.Name.Param.Ntype = t
|
v.Name().Param.Ntype = t
|
||||||
|
|
||||||
if e != nil || Curfn != nil || ir.IsBlank(v) {
|
if e != nil || Curfn != nil || ir.IsBlank(v) {
|
||||||
if Curfn != nil {
|
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)
|
e = ir.Nod(ir.OAS, v, e)
|
||||||
init = append(init, e)
|
init = append(init, e)
|
||||||
if e.Right != nil {
|
if e.Right() != nil {
|
||||||
v.Name.Defn = e
|
v.Name().Defn = e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -202,8 +202,8 @@ func newnoname(s *types.Sym) *ir.Node {
|
||||||
base.Fatalf("newnoname nil")
|
base.Fatalf("newnoname nil")
|
||||||
}
|
}
|
||||||
n := ir.Nod(ir.ONONAME, nil, nil)
|
n := ir.Nod(ir.ONONAME, nil, nil)
|
||||||
n.Sym = s
|
n.SetSym(s)
|
||||||
n.Xoffset = 0
|
n.SetOffset(0)
|
||||||
return n
|
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")
|
base.Fatalf("newfuncnamel - already have name")
|
||||||
}
|
}
|
||||||
n := ir.NewNameAt(pos, s)
|
n := ir.NewNameAt(pos, s)
|
||||||
n.Func = fn
|
n.SetFunc(fn)
|
||||||
fn.Nname = n
|
fn.Nname = n
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -222,7 +222,7 @@ func newfuncnamel(pos src.XPos, s *types.Sym, fn *ir.Func) *ir.Node {
|
||||||
// being declared.
|
// being declared.
|
||||||
func dclname(s *types.Sym) *ir.Node {
|
func dclname(s *types.Sym) *ir.Node {
|
||||||
n := NewName(s)
|
n := NewName(s)
|
||||||
n.Op = ir.ONONAME // caller will correct it
|
n.SetOp(ir.ONONAME) // caller will correct it
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,10 +234,10 @@ func typenodl(pos src.XPos, t *types.Type) *ir.Node {
|
||||||
// if we copied another type with *t = *u
|
// if we copied another type with *t = *u
|
||||||
// then t->nod might be out of date, so
|
// then t->nod might be out of date, so
|
||||||
// check t->nod->type too
|
// 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))
|
t.Nod = ir.AsTypesNode(ir.NodAt(pos, ir.OTYPE, nil, nil))
|
||||||
ir.AsNode(t.Nod).Type = t
|
ir.AsNode(t.Nod).SetType(t)
|
||||||
ir.AsNode(t.Nod).Sym = t.Sym
|
ir.AsNode(t.Nod).SetSym(t.Sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ir.AsNode(t.Nod)
|
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 {
|
func symfield(s *types.Sym, typ *types.Type) *ir.Node {
|
||||||
n := nodSym(ir.ODCLFIELD, nil, s)
|
n := nodSym(ir.ODCLFIELD, nil, s)
|
||||||
n.Type = typ
|
n.SetType(typ)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -270,28 +270,28 @@ func oldname(s *types.Sym) *ir.Node {
|
||||||
return newnoname(s)
|
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.
|
// Inner func is referring to var in outer func.
|
||||||
//
|
//
|
||||||
// TODO(rsc): If there is an outer variable x and we
|
// TODO(rsc): If there is an outer variable x and we
|
||||||
// are parsing x := 5 inside the closure, until we get to
|
// are parsing x := 5 inside the closure, until we get to
|
||||||
// the := it looks like a reference to the outer x so we'll
|
// the := it looks like a reference to the outer x so we'll
|
||||||
// make x a closure variable unnecessarily.
|
// make x a closure variable unnecessarily.
|
||||||
c := n.Name.Param.Innermost
|
c := n.Name().Param.Innermost
|
||||||
if c == nil || c.Name.Curfn != Curfn {
|
if c == nil || c.Name().Curfn != Curfn {
|
||||||
// Do not have a closure var for the active closure yet; make one.
|
// Do not have a closure var for the active closure yet; make one.
|
||||||
c = NewName(s)
|
c = NewName(s)
|
||||||
c.SetClass(ir.PAUTOHEAP)
|
c.SetClass(ir.PAUTOHEAP)
|
||||||
c.Name.SetIsClosureVar(true)
|
c.Name().SetIsClosureVar(true)
|
||||||
c.SetIsDDD(n.IsDDD())
|
c.SetIsDDD(n.IsDDD())
|
||||||
c.Name.Defn = n
|
c.Name().Defn = n
|
||||||
|
|
||||||
// Link into list of active closure variables.
|
// Link into list of active closure variables.
|
||||||
// Popped from list in func funcLit.
|
// Popped from list in func funcLit.
|
||||||
c.Name.Param.Outer = n.Name.Param.Innermost
|
c.Name().Param.Outer = n.Name().Param.Innermost
|
||||||
n.Name.Param.Innermost = c
|
n.Name().Param.Innermost = c
|
||||||
|
|
||||||
Curfn.Func.ClosureVars.Append(c)
|
Curfn.Func().ClosureVars.Append(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// return ref to closure var, not original
|
// return ref to closure var, not original
|
||||||
|
|
@ -313,13 +313,13 @@ func importName(sym *types.Sym) *ir.Node {
|
||||||
|
|
||||||
// := declarations
|
// := declarations
|
||||||
func colasname(n *ir.Node) bool {
|
func colasname(n *ir.Node) bool {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.ONAME,
|
case ir.ONAME,
|
||||||
ir.ONONAME,
|
ir.ONONAME,
|
||||||
ir.OPACK,
|
ir.OPACK,
|
||||||
ir.OTYPE,
|
ir.OTYPE,
|
||||||
ir.OLITERAL:
|
ir.OLITERAL:
|
||||||
return n.Sym != nil
|
return n.Sym() != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|
@ -327,8 +327,8 @@ func colasname(n *ir.Node) bool {
|
||||||
|
|
||||||
func colasdefn(left []*ir.Node, defn *ir.Node) {
|
func colasdefn(left []*ir.Node, defn *ir.Node) {
|
||||||
for _, n := range left {
|
for _, n := range left {
|
||||||
if n.Sym != nil {
|
if n.Sym() != nil {
|
||||||
n.Sym.SetUniq(true)
|
n.Sym().SetUniq(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -338,44 +338,44 @@ func colasdefn(left []*ir.Node, defn *ir.Node) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !colasname(n) {
|
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++
|
nerr++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !n.Sym.Uniq() {
|
if !n.Sym().Uniq() {
|
||||||
base.ErrorfAt(defn.Pos, "%v repeated on left side of :=", n.Sym)
|
base.ErrorfAt(defn.Pos(), "%v repeated on left side of :=", n.Sym())
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
nerr++
|
nerr++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Sym.SetUniq(false)
|
n.Sym().SetUniq(false)
|
||||||
if n.Sym.Block == types.Block {
|
if n.Sym().Block == types.Block {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
nnew++
|
nnew++
|
||||||
n = NewName(n.Sym)
|
n = NewName(n.Sym())
|
||||||
declare(n, dclcontext)
|
declare(n, dclcontext)
|
||||||
n.Name.Defn = defn
|
n.Name().Defn = defn
|
||||||
defn.Ninit.Append(ir.Nod(ir.ODCL, n, nil))
|
defn.PtrInit().Append(ir.Nod(ir.ODCL, n, nil))
|
||||||
left[i] = n
|
left[i] = n
|
||||||
}
|
}
|
||||||
|
|
||||||
if nnew == 0 && nerr == 0 {
|
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
|
// declare the arguments in an
|
||||||
// interface field declaration.
|
// interface field declaration.
|
||||||
func ifacedcl(n *ir.Node) {
|
func ifacedcl(n *ir.Node) {
|
||||||
if n.Op != ir.ODCLFIELD || n.Left == nil {
|
if n.Op() != ir.ODCLFIELD || n.Left() == nil {
|
||||||
base.Fatalf("ifacedcl")
|
base.Fatalf("ifacedcl")
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Sym.IsBlank() {
|
if n.Sym().IsBlank() {
|
||||||
base.Errorf("methods must have a unique non-blank name")
|
base.Errorf("methods must have a unique non-blank name")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -392,16 +392,16 @@ func funchdr(n *ir.Node) {
|
||||||
|
|
||||||
types.Markdcl()
|
types.Markdcl()
|
||||||
|
|
||||||
if n.Func.Nname != nil && n.Func.Nname.Name.Param.Ntype != nil {
|
if n.Func().Nname != nil && n.Func().Nname.Name().Param.Ntype != nil {
|
||||||
funcargs(n.Func.Nname.Name.Param.Ntype)
|
funcargs(n.Func().Nname.Name().Param.Ntype)
|
||||||
} else {
|
} else {
|
||||||
funcargs2(n.Type)
|
funcargs2(n.Type())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func funcargs(nt *ir.Node) {
|
func funcargs(nt *ir.Node) {
|
||||||
if nt.Op != ir.OTFUNC {
|
if nt.Op() != ir.OTFUNC {
|
||||||
base.Fatalf("funcargs %v", nt.Op)
|
base.Fatalf("funcargs %v", nt.Op())
|
||||||
}
|
}
|
||||||
|
|
||||||
// re-start the variable generation number
|
// re-start the variable generation number
|
||||||
|
|
@ -411,13 +411,13 @@ func funcargs(nt *ir.Node) {
|
||||||
// TODO(mdempsky): This is ugly, and only necessary because
|
// TODO(mdempsky): This is ugly, and only necessary because
|
||||||
// esc.go uses Vargen to figure out result parameters' index
|
// esc.go uses Vargen to figure out result parameters' index
|
||||||
// within the result tuple.
|
// within the result tuple.
|
||||||
vargen = nt.Rlist.Len()
|
vargen = nt.Rlist().Len()
|
||||||
|
|
||||||
// declare the receiver and in arguments.
|
// declare the receiver and in arguments.
|
||||||
if nt.Left != nil {
|
if nt.Left() != nil {
|
||||||
funcarg(nt.Left, ir.PPARAM)
|
funcarg(nt.Left(), ir.PPARAM)
|
||||||
}
|
}
|
||||||
for _, n := range nt.List.Slice() {
|
for _, n := range nt.List().Slice() {
|
||||||
funcarg(n, ir.PPARAM)
|
funcarg(n, ir.PPARAM)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -425,21 +425,21 @@ func funcargs(nt *ir.Node) {
|
||||||
vargen = 0
|
vargen = 0
|
||||||
|
|
||||||
// declare the out arguments.
|
// declare the out arguments.
|
||||||
gen := nt.List.Len()
|
gen := nt.List().Len()
|
||||||
for _, n := range nt.Rlist.Slice() {
|
for _, n := range nt.Rlist().Slice() {
|
||||||
if n.Sym == nil {
|
if n.Sym() == nil {
|
||||||
// Name so that escape analysis can track it. ~r stands for 'result'.
|
// Name so that escape analysis can track it. ~r stands for 'result'.
|
||||||
n.Sym = lookupN("~r", gen)
|
n.SetSym(lookupN("~r", gen))
|
||||||
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'.
|
// 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
|
// The name must be different from ~r above because if you have
|
||||||
// func f() (_ int)
|
// func f() (_ int)
|
||||||
// func g() int
|
// func g() int
|
||||||
// f is allowed to use a plain 'return' with no arguments, while g is not.
|
// f is allowed to use a plain 'return' with no arguments, while g is not.
|
||||||
// So the two cases must be distinguished.
|
// So the two cases must be distinguished.
|
||||||
n.Sym = lookupN("~b", gen)
|
n.SetSym(lookupN("~b", gen))
|
||||||
gen++
|
gen++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -450,20 +450,20 @@ func funcargs(nt *ir.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func funcarg(n *ir.Node, ctxt ir.Class) {
|
func funcarg(n *ir.Node, ctxt ir.Class) {
|
||||||
if n.Op != ir.ODCLFIELD {
|
if n.Op() != ir.ODCLFIELD {
|
||||||
base.Fatalf("funcarg %v", n.Op)
|
base.Fatalf("funcarg %v", n.Op())
|
||||||
}
|
}
|
||||||
if n.Sym == nil {
|
if n.Sym() == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Right = ir.NewNameAt(n.Pos, n.Sym)
|
n.SetRight(ir.NewNameAt(n.Pos(), n.Sym()))
|
||||||
n.Right.Name.Param.Ntype = n.Left
|
n.Right().Name().Param.Ntype = n.Left()
|
||||||
n.Right.SetIsDDD(n.IsDDD())
|
n.Right().SetIsDDD(n.IsDDD())
|
||||||
declare(n.Right, ctxt)
|
declare(n.Right(), ctxt)
|
||||||
|
|
||||||
vargen++
|
vargen++
|
||||||
n.Right.Name.Vargen = int32(vargen)
|
n.Right().Name().Vargen = int32(vargen)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as funcargs, except run over an already constructed TFUNC.
|
// 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)
|
n := ir.NewNameAt(f.Pos, f.Sym)
|
||||||
f.Nname = ir.AsTypesNode(n)
|
f.Nname = ir.AsTypesNode(n)
|
||||||
n.Type = f.Type
|
n.SetType(f.Type)
|
||||||
n.SetIsDDD(f.IsDDD())
|
n.SetIsDDD(f.IsDDD())
|
||||||
declare(n, ctxt)
|
declare(n, ctxt)
|
||||||
}
|
}
|
||||||
|
|
@ -537,21 +537,21 @@ func checkembeddedtype(t *types.Type) {
|
||||||
|
|
||||||
func structfield(n *ir.Node) *types.Field {
|
func structfield(n *ir.Node) *types.Field {
|
||||||
lno := base.Pos
|
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)
|
base.Fatalf("structfield: oops %v\n", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
n.Left = typecheck(n.Left, ctxType)
|
n.SetLeft(typecheck(n.Left(), ctxType))
|
||||||
n.Type = n.Left.Type
|
n.SetType(n.Left().Type())
|
||||||
n.Left = nil
|
n.SetLeft(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
f := types.NewField(n.Pos, n.Sym, n.Type)
|
f := types.NewField(n.Pos(), n.Sym(), n.Type())
|
||||||
if n.Embedded() {
|
if n.Embedded() {
|
||||||
checkembeddedtype(n.Type)
|
checkembeddedtype(n.Type())
|
||||||
f.Embedded = 1
|
f.Embedded = 1
|
||||||
}
|
}
|
||||||
if n.HasVal() {
|
if n.HasVal() {
|
||||||
|
|
@ -612,9 +612,9 @@ func tofunargs(l []*ir.Node, funarg types.Funarg) *types.Type {
|
||||||
for i, n := range l {
|
for i, n := range l {
|
||||||
f := structfield(n)
|
f := structfield(n)
|
||||||
f.SetIsDDD(n.IsDDD())
|
f.SetIsDDD(n.IsDDD())
|
||||||
if n.Right != nil {
|
if n.Right() != nil {
|
||||||
n.Right.Type = f.Type
|
n.Right().SetType(f.Type)
|
||||||
f.Nname = ir.AsTypesNode(n.Right)
|
f.Nname = ir.AsTypesNode(n.Right())
|
||||||
}
|
}
|
||||||
if f.Broke() {
|
if f.Broke() {
|
||||||
t.SetBroke(true)
|
t.SetBroke(true)
|
||||||
|
|
@ -634,9 +634,9 @@ func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type {
|
||||||
|
|
||||||
func interfacefield(n *ir.Node) *types.Field {
|
func interfacefield(n *ir.Node) *types.Field {
|
||||||
lno := base.Pos
|
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)
|
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.
|
// If Sym != nil, then Sym is MethodName and Left is Signature.
|
||||||
// Otherwise, Left is InterfaceTypeName.
|
// Otherwise, Left is InterfaceTypeName.
|
||||||
|
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
n.Left = typecheck(n.Left, ctxType)
|
n.SetLeft(typecheck(n.Left(), ctxType))
|
||||||
n.Type = n.Left.Type
|
n.SetType(n.Left().Type())
|
||||||
n.Left = nil
|
n.SetLeft(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
f := types.NewField(n.Pos, n.Sym, n.Type)
|
f := types.NewField(n.Pos(), n.Sym(), n.Type())
|
||||||
|
|
||||||
base.Pos = lno
|
base.Pos = lno
|
||||||
return f
|
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 := types.NewField(base.Pos, msym, t)
|
||||||
f.Nname = ir.AsTypesNode(n.Func.Nname)
|
f.Nname = ir.AsTypesNode(n.Func().Nname)
|
||||||
f.SetNointerface(nointerface)
|
f.SetNointerface(nointerface)
|
||||||
|
|
||||||
mt.Methods().Append(f)
|
mt.Methods().Append(f)
|
||||||
|
|
@ -936,26 +936,26 @@ func makefuncsym(s *types.Sym) {
|
||||||
|
|
||||||
// setNodeNameFunc marks a node as a function.
|
// setNodeNameFunc marks a node as a function.
|
||||||
func setNodeNameFunc(n *ir.Node) {
|
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)
|
base.Fatalf("expected ONAME/Pxxx node, got %v", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.SetClass(ir.PFUNC)
|
n.SetClass(ir.PFUNC)
|
||||||
n.Sym.SetFunc(true)
|
n.Sym().SetFunc(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func dclfunc(sym *types.Sym, tfn *ir.Node) *ir.Node {
|
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)
|
base.Fatalf("expected OTFUNC node, got %v", tfn)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := ir.Nod(ir.ODCLFUNC, nil, nil)
|
fn := ir.Nod(ir.ODCLFUNC, nil, nil)
|
||||||
fn.Func.Nname = newfuncnamel(base.Pos, sym, fn.Func)
|
fn.Func().Nname = newfuncnamel(base.Pos, sym, fn.Func())
|
||||||
fn.Func.Nname.Name.Defn = fn
|
fn.Func().Nname.Name().Defn = fn
|
||||||
fn.Func.Nname.Name.Param.Ntype = tfn
|
fn.Func().Nname.Name().Param.Ntype = tfn
|
||||||
setNodeNameFunc(fn.Func.Nname)
|
setNodeNameFunc(fn.Func().Nname)
|
||||||
funchdr(fn)
|
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
|
return fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -987,7 +987,7 @@ func newNowritebarrierrecChecker() *nowritebarrierrecChecker {
|
||||||
// directly. This has to happen before transformclosure since
|
// directly. This has to happen before transformclosure since
|
||||||
// it's a lot harder to work out the argument after.
|
// it's a lot harder to work out the argument after.
|
||||||
for _, n := range xtop {
|
for _, n := range xtop {
|
||||||
if n.Op != ir.ODCLFUNC {
|
if n.Op() != ir.ODCLFUNC {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
c.curfn = n
|
c.curfn = n
|
||||||
|
|
@ -998,31 +998,31 @@ func newNowritebarrierrecChecker() *nowritebarrierrecChecker {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *nowritebarrierrecChecker) findExtraCalls(n *ir.Node) bool {
|
func (c *nowritebarrierrecChecker) findExtraCalls(n *ir.Node) bool {
|
||||||
if n.Op != ir.OCALLFUNC {
|
if n.Op() != ir.OCALLFUNC {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
fn := n.Left
|
fn := n.Left()
|
||||||
if fn == nil || fn.Op != ir.ONAME || fn.Class() != ir.PFUNC || fn.Name.Defn == nil {
|
if fn == nil || fn.Op() != ir.ONAME || fn.Class() != ir.PFUNC || fn.Name().Defn == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if !isRuntimePkg(fn.Sym.Pkg) || fn.Sym.Name != "systemstack" {
|
if !isRuntimePkg(fn.Sym().Pkg) || fn.Sym().Name != "systemstack" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
var callee *ir.Node
|
var callee *ir.Node
|
||||||
arg := n.List.First()
|
arg := n.List().First()
|
||||||
switch arg.Op {
|
switch arg.Op() {
|
||||||
case ir.ONAME:
|
case ir.ONAME:
|
||||||
callee = arg.Name.Defn
|
callee = arg.Name().Defn
|
||||||
case ir.OCLOSURE:
|
case ir.OCLOSURE:
|
||||||
callee = arg.Func.Decl
|
callee = arg.Func().Decl
|
||||||
default:
|
default:
|
||||||
base.Fatalf("expected ONAME or OCLOSURE node, got %+v", arg)
|
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)
|
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
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1035,12 +1035,12 @@ func (c *nowritebarrierrecChecker) findExtraCalls(n *ir.Node) bool {
|
||||||
//
|
//
|
||||||
// This can be called concurrently for different from Nodes.
|
// This can be called concurrently for different from Nodes.
|
||||||
func (c *nowritebarrierrecChecker) recordCall(from *ir.Node, to *obj.LSym, pos src.XPos) {
|
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)
|
base.Fatalf("expected ODCLFUNC, got %v", from)
|
||||||
}
|
}
|
||||||
// We record this information on the *Func so this is
|
// We record this information on the *Func so this is
|
||||||
// concurrent-safe.
|
// concurrent-safe.
|
||||||
fn := from.Func
|
fn := from.Func()
|
||||||
if fn.NWBRCalls == nil {
|
if fn.NWBRCalls == nil {
|
||||||
fn.NWBRCalls = new([]ir.SymAndPos)
|
fn.NWBRCalls = new([]ir.SymAndPos)
|
||||||
}
|
}
|
||||||
|
|
@ -1064,27 +1064,27 @@ func (c *nowritebarrierrecChecker) check() {
|
||||||
var q ir.NodeQueue
|
var q ir.NodeQueue
|
||||||
|
|
||||||
for _, n := range xtop {
|
for _, n := range xtop {
|
||||||
if n.Op != ir.ODCLFUNC {
|
if n.Op() != ir.ODCLFUNC {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
symToFunc[n.Func.LSym] = n
|
symToFunc[n.Func().LSym] = n
|
||||||
|
|
||||||
// Make nowritebarrierrec functions BFS roots.
|
// Make nowritebarrierrec functions BFS roots.
|
||||||
if n.Func.Pragma&ir.Nowritebarrierrec != 0 {
|
if n.Func().Pragma&ir.Nowritebarrierrec != 0 {
|
||||||
funcs[n] = nowritebarrierrecCall{}
|
funcs[n] = nowritebarrierrecCall{}
|
||||||
q.PushRight(n)
|
q.PushRight(n)
|
||||||
}
|
}
|
||||||
// Check go:nowritebarrier functions.
|
// Check go:nowritebarrier functions.
|
||||||
if n.Func.Pragma&ir.Nowritebarrier != 0 && n.Func.WBPos.IsKnown() {
|
if n.Func().Pragma&ir.Nowritebarrier != 0 && n.Func().WBPos.IsKnown() {
|
||||||
base.ErrorfAt(n.Func.WBPos, "write barrier prohibited")
|
base.ErrorfAt(n.Func().WBPos, "write barrier prohibited")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform a BFS of the call graph from all
|
// Perform a BFS of the call graph from all
|
||||||
// go:nowritebarrierrec functions.
|
// go:nowritebarrierrec functions.
|
||||||
enqueue := func(src, target *ir.Node, pos src.XPos) {
|
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.
|
// Don't flow into this function.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1101,14 +1101,14 @@ func (c *nowritebarrierrecChecker) check() {
|
||||||
fn := q.PopLeft()
|
fn := q.PopLeft()
|
||||||
|
|
||||||
// Check fn.
|
// Check fn.
|
||||||
if fn.Func.WBPos.IsKnown() {
|
if fn.Func().WBPos.IsKnown() {
|
||||||
var err bytes.Buffer
|
var err bytes.Buffer
|
||||||
call := funcs[fn]
|
call := funcs[fn]
|
||||||
for call.target != nil {
|
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]
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1116,10 +1116,10 @@ func (c *nowritebarrierrecChecker) check() {
|
||||||
for _, callee := range c.extraCalls[fn] {
|
for _, callee := range c.extraCalls[fn] {
|
||||||
enqueue(fn, callee.target, callee.lineno)
|
enqueue(fn, callee.target, callee.lineno)
|
||||||
}
|
}
|
||||||
if fn.Func.NWBRCalls == nil {
|
if fn.Func().NWBRCalls == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, callee := range *fn.Func.NWBRCalls {
|
for _, callee := range *fn.Func().NWBRCalls {
|
||||||
target := symToFunc[callee.Sym]
|
target := symToFunc[callee.Sym]
|
||||||
if target != nil {
|
if target != nil {
|
||||||
enqueue(fn, target, callee.Pos)
|
enqueue(fn, target, callee.Pos)
|
||||||
|
|
|
||||||
|
|
@ -236,15 +236,15 @@ func makePreinlineDclMap(fnsym *obj.LSym) map[varPos]int {
|
||||||
dcl := preInliningDcls(fnsym)
|
dcl := preInliningDcls(fnsym)
|
||||||
m := make(map[varPos]int)
|
m := make(map[varPos]int)
|
||||||
for i, n := range dcl {
|
for i, n := range dcl {
|
||||||
pos := base.Ctxt.InnermostPos(n.Pos)
|
pos := base.Ctxt.InnermostPos(n.Pos())
|
||||||
vp := varPos{
|
vp := varPos{
|
||||||
DeclName: unversion(n.Sym.Name),
|
DeclName: unversion(n.Sym().Name),
|
||||||
DeclFile: pos.RelFilename(),
|
DeclFile: pos.RelFilename(),
|
||||||
DeclLine: pos.RelLine(),
|
DeclLine: pos.RelLine(),
|
||||||
DeclCol: pos.Col(),
|
DeclCol: pos.Col(),
|
||||||
}
|
}
|
||||||
if _, found := m[vp]; found {
|
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
|
m[vp] = i
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,15 +113,15 @@ func varEmbed(p *noder, names []*ir.Node, typ *ir.Node, exprs []*ir.Node, embeds
|
||||||
v := names[0]
|
v := names[0]
|
||||||
if dclcontext != ir.PEXTERN {
|
if dclcontext != ir.PEXTERN {
|
||||||
numLocalEmbed++
|
numLocalEmbed++
|
||||||
v = ir.NewNameAt(v.Pos, lookupN("embed.", numLocalEmbed))
|
v = ir.NewNameAt(v.Pos(), lookupN("embed.", numLocalEmbed))
|
||||||
v.Sym.Def = ir.AsTypesNode(v)
|
v.Sym().Def = ir.AsTypesNode(v)
|
||||||
v.Name.Param.Ntype = typ
|
v.Name().Param.Ntype = typ
|
||||||
v.SetClass(ir.PEXTERN)
|
v.SetClass(ir.PEXTERN)
|
||||||
externdcl = append(externdcl, v)
|
externdcl = append(externdcl, v)
|
||||||
exprs = []*ir.Node{v}
|
exprs = []*ir.Node{v}
|
||||||
}
|
}
|
||||||
|
|
||||||
v.Name.Param.SetEmbedFiles(list)
|
v.Name().Param.SetEmbedFiles(list)
|
||||||
embedlist = append(embedlist, v)
|
embedlist = append(embedlist, v)
|
||||||
return exprs
|
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".
|
// can't tell whether "string" and "byte" really mean "string" and "byte".
|
||||||
// The result must be confirmed later, after type checking, using embedKind.
|
// The result must be confirmed later, after type checking, using embedKind.
|
||||||
func embedKindApprox(typ *ir.Node) int {
|
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
|
return embedFiles
|
||||||
}
|
}
|
||||||
// These are not guaranteed to match only string and []byte -
|
// These are not guaranteed to match only string and []byte -
|
||||||
// maybe the local package has redefined one of those words.
|
// maybe the local package has redefined one of those words.
|
||||||
// But it's the best we can do now during the noder.
|
// But it's the best we can do now during the noder.
|
||||||
// The stricter check happens later, in initEmbed calling embedKind.
|
// 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
|
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 embedBytes
|
||||||
}
|
}
|
||||||
return embedUnknown
|
return embedUnknown
|
||||||
|
|
@ -193,18 +193,18 @@ func dumpembeds() {
|
||||||
// initEmbed emits the init data for a //go:embed variable,
|
// initEmbed emits the init data for a //go:embed variable,
|
||||||
// which is either a string, a []byte, or an embed.FS.
|
// which is either a string, a []byte, or an embed.FS.
|
||||||
func initEmbed(v *ir.Node) {
|
func initEmbed(v *ir.Node) {
|
||||||
files := v.Name.Param.EmbedFiles()
|
files := v.Name().Param.EmbedFiles()
|
||||||
switch kind := embedKind(v.Type); kind {
|
switch kind := embedKind(v.Type()); kind {
|
||||||
case embedUnknown:
|
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:
|
case embedString, embedBytes:
|
||||||
file := files[0]
|
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 {
|
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 := 0
|
||||||
off = dsymptr(sym, off, fsym, 0) // data string
|
off = dsymptr(sym, off, fsym, 0) // data string
|
||||||
off = duintptr(sym, off, uint64(size)) // len
|
off = duintptr(sym, off, uint64(size)) // len
|
||||||
|
|
@ -213,7 +213,7 @@ func initEmbed(v *ir.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case embedFiles:
|
case embedFiles:
|
||||||
slicedata := base.Ctxt.Lookup(`"".` + v.Sym.Name + `.files`)
|
slicedata := base.Ctxt.Lookup(`"".` + v.Sym().Name + `.files`)
|
||||||
off := 0
|
off := 0
|
||||||
// []files pointed at by Files
|
// []files pointed at by Files
|
||||||
off = dsymptr(slicedata, off, slicedata, 3*Widthptr) // []file, pointing just past slice
|
off = dsymptr(slicedata, off, slicedata, 3*Widthptr) // []file, pointing just past slice
|
||||||
|
|
@ -228,7 +228,7 @@ func initEmbed(v *ir.Node) {
|
||||||
const hashSize = 16
|
const hashSize = 16
|
||||||
hash := make([]byte, hashSize)
|
hash := make([]byte, hashSize)
|
||||||
for _, file := range files {
|
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)))
|
off = duintptr(slicedata, off, uint64(len(file)))
|
||||||
if strings.HasSuffix(file, "/") {
|
if strings.HasSuffix(file, "/") {
|
||||||
// entry for directory - no data
|
// entry for directory - no data
|
||||||
|
|
@ -236,9 +236,9 @@ func initEmbed(v *ir.Node) {
|
||||||
off = duintptr(slicedata, off, 0)
|
off = duintptr(slicedata, off, 0)
|
||||||
off += hashSize
|
off += hashSize
|
||||||
} else {
|
} 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 {
|
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 = dsymptr(slicedata, off, fsym, 0) // data string
|
||||||
off = duintptr(slicedata, off, uint64(size))
|
off = duintptr(slicedata, off, uint64(size))
|
||||||
|
|
@ -246,7 +246,7 @@ func initEmbed(v *ir.Node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ggloblsym(slicedata, int32(off), obj.RODATA|obj.LOCAL)
|
ggloblsym(slicedata, int32(off), obj.RODATA|obj.LOCAL)
|
||||||
sym := v.Sym.Linksym()
|
sym := v.Sym().Linksym()
|
||||||
dsymptr(sym, 0, slicedata, 0)
|
dsymptr(sym, 0, slicedata, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -25,13 +25,13 @@ var asmlist []*ir.Node
|
||||||
|
|
||||||
// exportsym marks n for export (or reexport).
|
// exportsym marks n for export (or reexport).
|
||||||
func exportsym(n *ir.Node) {
|
func exportsym(n *ir.Node) {
|
||||||
if n.Sym.OnExportList() {
|
if n.Sym().OnExportList() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n.Sym.SetOnExportList(true)
|
n.Sym().SetOnExportList(true)
|
||||||
|
|
||||||
if base.Flag.E != 0 {
|
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)
|
exportlist = append(exportlist, n)
|
||||||
|
|
@ -42,21 +42,21 @@ func initname(s string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func autoexport(n *ir.Node, ctxt ir.Class) {
|
func autoexport(n *ir.Node, ctxt ir.Class) {
|
||||||
if n.Sym.Pkg != ir.LocalPkg {
|
if n.Sym().Pkg != ir.LocalPkg {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (ctxt != ir.PEXTERN && ctxt != ir.PFUNC) || dclcontext != ir.PEXTERN {
|
if (ctxt != ir.PEXTERN && ctxt != ir.PFUNC) || dclcontext != ir.PEXTERN {
|
||||||
return
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if types.IsExported(n.Sym.Name) || initname(n.Sym.Name) {
|
if types.IsExported(n.Sym().Name) || initname(n.Sym().Name) {
|
||||||
exportsym(n)
|
exportsym(n)
|
||||||
}
|
}
|
||||||
if base.Flag.AsmHdr != "" && !n.Sym.Asm() {
|
if base.Flag.AsmHdr != "" && !n.Sym().Asm() {
|
||||||
n.Sym.SetAsm(true)
|
n.Sym().SetAsm(true)
|
||||||
asmlist = append(asmlist, n)
|
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.SetPkgDef(ir.AsTypesNode(n))
|
||||||
s.Importdef = ipkg
|
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))
|
redeclare(base.Pos, s, fmt.Sprintf("during import %q", ipkg.Path))
|
||||||
}
|
}
|
||||||
return n
|
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
|
// ipkg is the package being imported
|
||||||
func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
|
func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
|
||||||
n := importsym(ipkg, s, ir.OTYPE)
|
n := importsym(ipkg, s, ir.OTYPE)
|
||||||
if n.Op != ir.OTYPE {
|
if n.Op() != ir.OTYPE {
|
||||||
t := types.New(types.TFORW)
|
t := types.New(types.TFORW)
|
||||||
t.Sym = s
|
t.Sym = s
|
||||||
t.Nod = ir.AsTypesNode(n)
|
t.Nod = ir.AsTypesNode(n)
|
||||||
|
|
||||||
n.Op = ir.OTYPE
|
n.SetOp(ir.OTYPE)
|
||||||
n.Pos = pos
|
n.SetPos(pos)
|
||||||
n.Type = t
|
n.SetType(t)
|
||||||
n.SetClass(ir.PEXTERN)
|
n.SetClass(ir.PEXTERN)
|
||||||
}
|
}
|
||||||
|
|
||||||
t := n.Type
|
t := n.Type()
|
||||||
if t == nil {
|
if t == nil {
|
||||||
base.Fatalf("importtype %v", s)
|
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
|
// 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 {
|
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)
|
n := importsym(ipkg, s, op)
|
||||||
if n.Op != ir.ONONAME {
|
if n.Op() != ir.ONONAME {
|
||||||
if n.Op == op && (n.Class() != ctxt || !types.Identical(n.Type, t)) {
|
if n.Op() == op && (n.Class() != ctxt || !types.Identical(n.Type(), t)) {
|
||||||
redeclare(base.Pos, s, fmt.Sprintf("during import %q", ipkg.Path))
|
redeclare(base.Pos, s, fmt.Sprintf("during import %q", ipkg.Path))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Op = op
|
n.SetOp(op)
|
||||||
n.Pos = pos
|
n.SetPos(pos)
|
||||||
n.SetClass(ctxt)
|
n.SetClass(ctxt)
|
||||||
if ctxt == ir.PFUNC {
|
if ctxt == ir.PFUNC {
|
||||||
n.Sym.SetFunc(true)
|
n.Sym().SetFunc(true)
|
||||||
}
|
}
|
||||||
n.Type = t
|
n.SetType(t)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,7 +162,7 @@ func importfunc(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Func = new(ir.Func)
|
n.SetFunc(new(ir.Func))
|
||||||
|
|
||||||
if base.Flag.E != 0 {
|
if base.Flag.E != 0 {
|
||||||
fmt.Printf("import func %v%S\n", s, t)
|
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)
|
fmt.Fprintf(b, "// generated by compile -asmhdr from package %s\n\n", ir.LocalPkg.Name)
|
||||||
for _, n := range asmlist {
|
for _, n := range asmlist {
|
||||||
if n.Sym.IsBlank() {
|
if n.Sym().IsBlank() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.OLITERAL:
|
case ir.OLITERAL:
|
||||||
t := n.Val().Kind()
|
t := n.Val().Kind()
|
||||||
if t == constant.Float || t == constant.Complex {
|
if t == constant.Float || t == constant.Complex {
|
||||||
break
|
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:
|
case ir.OTYPE:
|
||||||
t := n.Type
|
t := n.Type()
|
||||||
if !t.IsStruct() || t.StructType().Map != nil || t.IsFuncArgStruct() {
|
if !t.IsStruct() || t.StructType().Map != nil || t.IsFuncArgStruct() {
|
||||||
break
|
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() {
|
for _, f := range t.Fields().Slice() {
|
||||||
if !f.Sym.IsBlank() {
|
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,13 @@ func sysvar(name string) *obj.LSym {
|
||||||
// isParamStackCopy reports whether this is the on-stack copy of a
|
// isParamStackCopy reports whether this is the on-stack copy of a
|
||||||
// function parameter that moved to the heap.
|
// function parameter that moved to the heap.
|
||||||
func isParamStackCopy(n *ir.Node) bool {
|
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
|
// isParamHeapCopy reports whether this is the on-heap copy of
|
||||||
// a function parameter that moved to the heap.
|
// a function parameter that moved to the heap.
|
||||||
func isParamHeapCopy(n *ir.Node) bool {
|
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.
|
// 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 {
|
if curfn == nil {
|
||||||
base.Fatalf("no curfn for tempAt")
|
base.Fatalf("no curfn for tempAt")
|
||||||
}
|
}
|
||||||
if curfn.Op == ir.OCLOSURE {
|
if curfn.Op() == ir.OCLOSURE {
|
||||||
ir.Dump("tempAt", curfn)
|
ir.Dump("tempAt", curfn)
|
||||||
base.Fatalf("adding tempAt to wrong closure function")
|
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{
|
s := &types.Sym{
|
||||||
Name: autotmpname(len(curfn.Func.Dcl)),
|
Name: autotmpname(len(curfn.Func().Dcl)),
|
||||||
Pkg: ir.LocalPkg,
|
Pkg: ir.LocalPkg,
|
||||||
}
|
}
|
||||||
n := ir.NewNameAt(pos, s)
|
n := ir.NewNameAt(pos, s)
|
||||||
s.Def = ir.AsTypesNode(n)
|
s.Def = ir.AsTypesNode(n)
|
||||||
n.Type = t
|
n.SetType(t)
|
||||||
n.SetClass(ir.PAUTO)
|
n.SetClass(ir.PAUTO)
|
||||||
n.Esc = EscNever
|
n.SetEsc(EscNever)
|
||||||
n.Name.Curfn = curfn
|
n.Name().Curfn = curfn
|
||||||
n.Name.SetUsed(true)
|
n.Name().SetUsed(true)
|
||||||
n.Name.SetAutoTemp(true)
|
n.Name().SetAutoTemp(true)
|
||||||
curfn.Func.Dcl = append(curfn.Func.Dcl, n)
|
curfn.Func().Dcl = append(curfn.Func().Dcl, n)
|
||||||
|
|
||||||
dowidth(t)
|
dowidth(t)
|
||||||
|
|
||||||
return n.Orig
|
return n.Orig()
|
||||||
}
|
}
|
||||||
|
|
||||||
func temp(t *types.Type) *ir.Node {
|
func temp(t *types.Type) *ir.Node {
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ func newProgs(fn *ir.Node, worker int) *Progs {
|
||||||
pp.next = pp.NewProg()
|
pp.next = pp.NewProg()
|
||||||
pp.clearp(pp.next)
|
pp.clearp(pp.next)
|
||||||
|
|
||||||
pp.pos = fn.Pos
|
pp.pos = fn.Pos()
|
||||||
pp.settext(fn)
|
pp.settext(fn)
|
||||||
// PCDATA tables implicitly start with index -1.
|
// PCDATA tables implicitly start with index -1.
|
||||||
pp.prevLive = LivenessIndex{-1, false}
|
pp.prevLive = LivenessIndex{-1, false}
|
||||||
|
|
@ -181,10 +181,10 @@ func (pp *Progs) settext(fn *ir.Node) {
|
||||||
ptxt := pp.Prog(obj.ATEXT)
|
ptxt := pp.Prog(obj.ATEXT)
|
||||||
pp.Text = ptxt
|
pp.Text = ptxt
|
||||||
|
|
||||||
fn.Func.LSym.Func().Text = ptxt
|
fn.Func().LSym.Func().Text = ptxt
|
||||||
ptxt.From.Type = obj.TYPE_MEM
|
ptxt.From.Type = obj.TYPE_MEM
|
||||||
ptxt.From.Name = obj.NAME_EXTERN
|
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
|
// 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) {
|
if nam := f.Nname; !ir.IsBlank(nam) {
|
||||||
f.LSym = nam.Sym.Linksym()
|
f.LSym = nam.Sym().Linksym()
|
||||||
if f.Pragma&ir.Systemstack != 0 {
|
if f.Pragma&ir.Systemstack != 0 {
|
||||||
f.LSym.Set(obj.AttrCFunc, true)
|
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 {
|
if abi, ok := symabiRefs[f.LSym.Name]; (ok && abi == obj.ABI0) || isLinknameExported {
|
||||||
// Either 1) this symbol is definitely
|
// Either 1) this symbol is definitely
|
||||||
// referenced as ABI0 from this package; or 2)
|
// 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
|
// See test/recover.go for test cases and src/reflect/value.go
|
||||||
// for the actual functions being considered.
|
// for the actual functions being considered.
|
||||||
if base.Ctxt.Pkgpath == "reflect" {
|
if base.Ctxt.Pkgpath == "reflect" {
|
||||||
switch f.Nname.Sym.Name {
|
switch f.Nname.Sym().Name {
|
||||||
case "callReflect", "callMethod":
|
case "callReflect", "callMethod":
|
||||||
flag |= obj.WRAPPER
|
flag |= obj.WRAPPER
|
||||||
}
|
}
|
||||||
|
|
@ -291,20 +291,20 @@ func initLSym(f *ir.Func, hasBody bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ggloblnod(nam *ir.Node) {
|
func ggloblnod(nam *ir.Node) {
|
||||||
s := nam.Sym.Linksym()
|
s := nam.Sym().Linksym()
|
||||||
s.Gotype = ngotype(nam).Linksym()
|
s.Gotype = ngotype(nam).Linksym()
|
||||||
flags := 0
|
flags := 0
|
||||||
if nam.Name.Readonly() {
|
if nam.Name().Readonly() {
|
||||||
flags = obj.RODATA
|
flags = obj.RODATA
|
||||||
}
|
}
|
||||||
if nam.Type != nil && !nam.Type.HasPointers() {
|
if nam.Type() != nil && !nam.Type().HasPointers() {
|
||||||
flags |= obj.NOPTR
|
flags |= obj.NOPTR
|
||||||
}
|
}
|
||||||
base.Ctxt.Globl(s, nam.Type.Width, flags)
|
base.Ctxt.Globl(s, nam.Type().Width, flags)
|
||||||
if nam.Name.LibfuzzerExtraCounter() {
|
if nam.Name().LibfuzzerExtraCounter() {
|
||||||
s.Type = objabi.SLIBFUZZER_EXTRA_COUNTER
|
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
|
// Make sure linkname'd symbol is non-package. When a symbol is
|
||||||
// both imported and linkname'd, s.Pkg may not set to "_" in
|
// both imported and linkname'd, s.Pkg may not set to "_" in
|
||||||
// types.Sym.Linksym because LSym already exists. Set it here.
|
// types.Sym.Linksym because LSym already exists. Set it here.
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@ func (w *exportWriter) writeIndex(index map[*ir.Node]uint64, mainIndex bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for n := range index {
|
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
|
var pkgs []*types.Pkg
|
||||||
|
|
@ -337,7 +337,7 @@ func (w *exportWriter) writeIndex(index map[*ir.Node]uint64, mainIndex bool) {
|
||||||
pkgs = append(pkgs, pkg)
|
pkgs = append(pkgs, pkg)
|
||||||
|
|
||||||
sort.Slice(objs, func(i, j int) bool {
|
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]
|
objs := pkgObjs[pkg]
|
||||||
w.uint64(uint64(len(objs)))
|
w.uint64(uint64(len(objs)))
|
||||||
for _, n := range objs {
|
for _, n := range objs {
|
||||||
w.string(n.Sym.Name)
|
w.string(n.Sym().Name)
|
||||||
w.uint64(index[n])
|
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.
|
// pushDecl adds n to the declaration work queue, if not already present.
|
||||||
func (p *iexporter) pushDecl(n *ir.Node) {
|
func (p *iexporter) pushDecl(n *ir.Node) {
|
||||||
if n.Sym == nil || ir.AsNode(n.Sym.Def) != n && n.Op != ir.OTYPE {
|
if n.Sym() == nil || ir.AsNode(n.Sym().Def) != n && n.Op() != ir.OTYPE {
|
||||||
base.Fatalf("weird Sym: %v, %v", n, n.Sym)
|
base.Fatalf("weird Sym: %v, %v", n, n.Sym())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't export predeclared declarations.
|
// 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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -425,16 +425,16 @@ type exportWriter struct {
|
||||||
|
|
||||||
func (p *iexporter) doDecl(n *ir.Node) {
|
func (p *iexporter) doDecl(n *ir.Node) {
|
||||||
w := p.newWriter()
|
w := p.newWriter()
|
||||||
w.setPkg(n.Sym.Pkg, false)
|
w.setPkg(n.Sym().Pkg, false)
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.ONAME:
|
case ir.ONAME:
|
||||||
switch n.Class() {
|
switch n.Class() {
|
||||||
case ir.PEXTERN:
|
case ir.PEXTERN:
|
||||||
// Variable.
|
// Variable.
|
||||||
w.tag('V')
|
w.tag('V')
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.typ(n.Type)
|
w.typ(n.Type())
|
||||||
w.varExt(n)
|
w.varExt(n)
|
||||||
|
|
||||||
case ir.PFUNC:
|
case ir.PFUNC:
|
||||||
|
|
@ -444,8 +444,8 @@ func (p *iexporter) doDecl(n *ir.Node) {
|
||||||
|
|
||||||
// Function.
|
// Function.
|
||||||
w.tag('F')
|
w.tag('F')
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.signature(n.Type)
|
w.signature(n.Type())
|
||||||
w.funcExt(n)
|
w.funcExt(n)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -456,23 +456,23 @@ func (p *iexporter) doDecl(n *ir.Node) {
|
||||||
// Constant.
|
// Constant.
|
||||||
n = typecheck(n, ctxExpr)
|
n = typecheck(n, ctxExpr)
|
||||||
w.tag('C')
|
w.tag('C')
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.value(n.Type, n.Val())
|
w.value(n.Type(), n.Val())
|
||||||
|
|
||||||
case ir.OTYPE:
|
case ir.OTYPE:
|
||||||
if IsAlias(n.Sym) {
|
if IsAlias(n.Sym()) {
|
||||||
// Alias.
|
// Alias.
|
||||||
w.tag('A')
|
w.tag('A')
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.typ(n.Type)
|
w.typ(n.Type())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defined type.
|
// Defined type.
|
||||||
w.tag('T')
|
w.tag('T')
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
|
|
||||||
underlying := n.Type.Orig
|
underlying := n.Type().Orig
|
||||||
if underlying == types.Errortype.Orig {
|
if underlying == types.Errortype.Orig {
|
||||||
// For "type T error", use error as the
|
// For "type T error", use error as the
|
||||||
// underlying type instead of error's own
|
// underlying type instead of error's own
|
||||||
|
|
@ -484,7 +484,7 @@ func (p *iexporter) doDecl(n *ir.Node) {
|
||||||
}
|
}
|
||||||
w.typ(underlying)
|
w.typ(underlying)
|
||||||
|
|
||||||
t := n.Type
|
t := n.Type()
|
||||||
if t.IsInterface() {
|
if t.IsInterface() {
|
||||||
w.typeExt(t)
|
w.typeExt(t)
|
||||||
break
|
break
|
||||||
|
|
@ -519,7 +519,7 @@ func (p *iexporter) doInline(f *ir.Node) {
|
||||||
w := p.newWriter()
|
w := p.newWriter()
|
||||||
w.setPkg(fnpkg(f), false)
|
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()
|
p.inlineIndex[f] = w.flush()
|
||||||
}
|
}
|
||||||
|
|
@ -574,7 +574,7 @@ func (w *exportWriter) qualifiedIdent(n *ir.Node) {
|
||||||
// Ensure any referenced declarations are written out too.
|
// Ensure any referenced declarations are written out too.
|
||||||
w.p.pushDecl(n)
|
w.p.pushDecl(n)
|
||||||
|
|
||||||
s := n.Sym
|
s := n.Sym()
|
||||||
w.string(s.Name)
|
w.string(s.Name)
|
||||||
w.pkg(s.Pkg)
|
w.pkg(s.Pkg)
|
||||||
}
|
}
|
||||||
|
|
@ -956,36 +956,36 @@ func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) }
|
||||||
// Compiler-specific extensions.
|
// Compiler-specific extensions.
|
||||||
|
|
||||||
func (w *exportWriter) varExt(n *ir.Node) {
|
func (w *exportWriter) varExt(n *ir.Node) {
|
||||||
w.linkname(n.Sym)
|
w.linkname(n.Sym())
|
||||||
w.symIdx(n.Sym)
|
w.symIdx(n.Sym())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *exportWriter) funcExt(n *ir.Node) {
|
func (w *exportWriter) funcExt(n *ir.Node) {
|
||||||
w.linkname(n.Sym)
|
w.linkname(n.Sym())
|
||||||
w.symIdx(n.Sym)
|
w.symIdx(n.Sym())
|
||||||
|
|
||||||
// Escape analysis.
|
// Escape analysis.
|
||||||
for _, fs := range &types.RecvsParams {
|
for _, fs := range &types.RecvsParams {
|
||||||
for _, f := range fs(n.Type).FieldSlice() {
|
for _, f := range fs(n.Type()).FieldSlice() {
|
||||||
w.string(f.Note)
|
w.string(f.Note)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inline body.
|
// Inline body.
|
||||||
if n.Func.Inl != nil {
|
if n.Func().Inl != nil {
|
||||||
w.uint64(1 + uint64(n.Func.Inl.Cost))
|
w.uint64(1 + uint64(n.Func().Inl.Cost))
|
||||||
if n.Func.ExportInline() {
|
if n.Func().ExportInline() {
|
||||||
w.p.doInline(n)
|
w.p.doInline(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Endlineno for inlined function.
|
// Endlineno for inlined function.
|
||||||
if n.Name.Defn != nil {
|
if n.Name().Defn != nil {
|
||||||
w.pos(n.Name.Defn.Func.Endlineno)
|
w.pos(n.Name().Defn.Func().Endlineno)
|
||||||
} else {
|
} else {
|
||||||
// When the exported node was defined externally,
|
// When the exported node was defined externally,
|
||||||
// e.g. io exports atomic.(*Value).Load or bytes exports errors.New.
|
// e.g. io exports atomic.(*Value).Load or bytes exports errors.New.
|
||||||
// Keep it as we don't distinguish this case in iimport.go.
|
// Keep it as we don't distinguish this case in iimport.go.
|
||||||
w.pos(n.Func.Endlineno)
|
w.pos(n.Func().Endlineno)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
w.uint64(0)
|
w.uint64(0)
|
||||||
|
|
@ -1038,7 +1038,7 @@ func (w *exportWriter) stmtList(list ir.Nodes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *exportWriter) node(n *ir.Node) {
|
func (w *exportWriter) node(n *ir.Node) {
|
||||||
if ir.OpPrec[n.Op] < 0 {
|
if ir.OpPrec[n.Op()] < 0 {
|
||||||
w.stmt(n)
|
w.stmt(n)
|
||||||
} else {
|
} else {
|
||||||
w.expr(n)
|
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
|
// 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.).
|
// n.Ninit and where n cannot have a natural init section (such as in "if", "for", etc.).
|
||||||
func (w *exportWriter) stmt(n *ir.Node) {
|
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
|
// 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)
|
w.stmt(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch op := n.Op; op {
|
switch op := n.Op(); op {
|
||||||
case ir.ODCL:
|
case ir.ODCL:
|
||||||
w.op(ir.ODCL)
|
w.op(ir.ODCL)
|
||||||
w.pos(n.Left.Pos)
|
w.pos(n.Left().Pos())
|
||||||
w.localName(n.Left)
|
w.localName(n.Left())
|
||||||
w.typ(n.Left.Type)
|
w.typ(n.Left().Type())
|
||||||
|
|
||||||
// case ODCLFIELD:
|
// case ODCLFIELD:
|
||||||
// unimplemented - handled by default case
|
// unimplemented - handled by default case
|
||||||
|
|
@ -1069,74 +1069,74 @@ func (w *exportWriter) stmt(n *ir.Node) {
|
||||||
// Don't export "v = <N>" initializing statements, hope they're always
|
// Don't export "v = <N>" initializing statements, hope they're always
|
||||||
// preceded by the DCL which will be re-parsed and typecheck to reproduce
|
// preceded by the DCL which will be re-parsed and typecheck to reproduce
|
||||||
// the "v = <N>" again.
|
// the "v = <N>" again.
|
||||||
if n.Right != nil {
|
if n.Right() != nil {
|
||||||
w.op(ir.OAS)
|
w.op(ir.OAS)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
w.expr(n.Right)
|
w.expr(n.Right())
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OASOP:
|
case ir.OASOP:
|
||||||
w.op(ir.OASOP)
|
w.op(ir.OASOP)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.op(n.SubOp())
|
w.op(n.SubOp())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
if w.bool(!n.Implicit()) {
|
if w.bool(!n.Implicit()) {
|
||||||
w.expr(n.Right)
|
w.expr(n.Right())
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OAS2:
|
case ir.OAS2:
|
||||||
w.op(ir.OAS2)
|
w.op(ir.OAS2)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.exprList(n.List)
|
w.exprList(n.List())
|
||||||
w.exprList(n.Rlist)
|
w.exprList(n.Rlist())
|
||||||
|
|
||||||
case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
|
case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
|
||||||
w.op(ir.OAS2)
|
w.op(ir.OAS2)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.exprList(n.List)
|
w.exprList(n.List())
|
||||||
w.exprList(ir.AsNodes([]*ir.Node{n.Right}))
|
w.exprList(ir.AsNodes([]*ir.Node{n.Right()}))
|
||||||
|
|
||||||
case ir.ORETURN:
|
case ir.ORETURN:
|
||||||
w.op(ir.ORETURN)
|
w.op(ir.ORETURN)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.exprList(n.List)
|
w.exprList(n.List())
|
||||||
|
|
||||||
// case ORETJMP:
|
// case ORETJMP:
|
||||||
// unreachable - generated by compiler for trampolin routines
|
// unreachable - generated by compiler for trampolin routines
|
||||||
|
|
||||||
case ir.OGO, ir.ODEFER:
|
case ir.OGO, ir.ODEFER:
|
||||||
w.op(op)
|
w.op(op)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
|
|
||||||
case ir.OIF:
|
case ir.OIF:
|
||||||
w.op(ir.OIF)
|
w.op(ir.OIF)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.stmtList(n.Ninit)
|
w.stmtList(n.Init())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
w.stmtList(n.Nbody)
|
w.stmtList(n.Body())
|
||||||
w.stmtList(n.Rlist)
|
w.stmtList(n.Rlist())
|
||||||
|
|
||||||
case ir.OFOR:
|
case ir.OFOR:
|
||||||
w.op(ir.OFOR)
|
w.op(ir.OFOR)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.stmtList(n.Ninit)
|
w.stmtList(n.Init())
|
||||||
w.exprsOrNil(n.Left, n.Right)
|
w.exprsOrNil(n.Left(), n.Right())
|
||||||
w.stmtList(n.Nbody)
|
w.stmtList(n.Body())
|
||||||
|
|
||||||
case ir.ORANGE:
|
case ir.ORANGE:
|
||||||
w.op(ir.ORANGE)
|
w.op(ir.ORANGE)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.stmtList(n.List)
|
w.stmtList(n.List())
|
||||||
w.expr(n.Right)
|
w.expr(n.Right())
|
||||||
w.stmtList(n.Nbody)
|
w.stmtList(n.Body())
|
||||||
|
|
||||||
case ir.OSELECT, ir.OSWITCH:
|
case ir.OSELECT, ir.OSWITCH:
|
||||||
w.op(op)
|
w.op(op)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.stmtList(n.Ninit)
|
w.stmtList(n.Init())
|
||||||
w.exprsOrNil(n.Left, nil)
|
w.exprsOrNil(n.Left(), nil)
|
||||||
w.caseList(n)
|
w.caseList(n)
|
||||||
|
|
||||||
// case OCASE:
|
// case OCASE:
|
||||||
|
|
@ -1144,41 +1144,41 @@ func (w *exportWriter) stmt(n *ir.Node) {
|
||||||
|
|
||||||
case ir.OFALL:
|
case ir.OFALL:
|
||||||
w.op(ir.OFALL)
|
w.op(ir.OFALL)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
|
|
||||||
case ir.OBREAK, ir.OCONTINUE:
|
case ir.OBREAK, ir.OCONTINUE:
|
||||||
w.op(op)
|
w.op(op)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.exprsOrNil(n.Left, nil)
|
w.exprsOrNil(n.Left(), nil)
|
||||||
|
|
||||||
case ir.OEMPTY:
|
case ir.OEMPTY:
|
||||||
// nothing to emit
|
// nothing to emit
|
||||||
|
|
||||||
case ir.OGOTO, ir.OLABEL:
|
case ir.OGOTO, ir.OLABEL:
|
||||||
w.op(op)
|
w.op(op)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.string(n.Sym.Name)
|
w.string(n.Sym().Name)
|
||||||
|
|
||||||
default:
|
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) {
|
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)))
|
w.uint64(uint64(len(cases)))
|
||||||
for _, cas := range cases {
|
for _, cas := range cases {
|
||||||
if cas.Op != ir.OCASE {
|
if cas.Op() != ir.OCASE {
|
||||||
base.Fatalf("expected OCASE, got %v", cas)
|
base.Fatalf("expected OCASE, got %v", cas)
|
||||||
}
|
}
|
||||||
w.pos(cas.Pos)
|
w.pos(cas.Pos())
|
||||||
w.stmtList(cas.List)
|
w.stmtList(cas.List())
|
||||||
if namedTypeSwitch {
|
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)
|
// 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) {
|
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
|
n = n.Left()
|
||||||
}
|
}
|
||||||
|
|
||||||
switch op := n.Op; op {
|
switch op := n.Op(); op {
|
||||||
// expressions
|
// expressions
|
||||||
// (somewhat closely following the structure of exprfmt in fmt.go)
|
// (somewhat closely following the structure of exprfmt in fmt.go)
|
||||||
case ir.ONIL:
|
case ir.ONIL:
|
||||||
if !n.Type.HasNil() {
|
if !n.Type().HasNil() {
|
||||||
base.Fatalf("unexpected type for nil: %v", n.Type)
|
base.Fatalf("unexpected type for nil: %v", n.Type())
|
||||||
}
|
}
|
||||||
if n.Orig != nil && n.Orig != n {
|
if n.Orig() != nil && n.Orig() != n {
|
||||||
w.expr(n.Orig)
|
w.expr(n.Orig())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
w.op(ir.OLITERAL)
|
w.op(ir.OLITERAL)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.typ(n.Type)
|
w.typ(n.Type())
|
||||||
|
|
||||||
case ir.OLITERAL:
|
case ir.OLITERAL:
|
||||||
w.op(ir.OLITERAL)
|
w.op(ir.OLITERAL)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.value(n.Type, n.Val())
|
w.value(n.Type(), n.Val())
|
||||||
|
|
||||||
case ir.OMETHEXPR:
|
case ir.OMETHEXPR:
|
||||||
// Special case: explicit name of func (*T) method(...) is turned into pkg.(*T).method,
|
// 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.
|
// 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.
|
// These nodes have the special property that they are names with a left OTYPE and a right ONAME.
|
||||||
w.op(ir.OXDOT)
|
w.op(ir.OXDOT)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left) // n.Left.Op == OTYPE
|
w.expr(n.Left()) // n.Left.Op == OTYPE
|
||||||
w.selector(n.Right.Sym)
|
w.selector(n.Right().Sym())
|
||||||
|
|
||||||
case ir.ONAME:
|
case ir.ONAME:
|
||||||
// Package scope name.
|
// Package scope name.
|
||||||
|
|
@ -1250,20 +1250,20 @@ func (w *exportWriter) expr(n *ir.Node) {
|
||||||
|
|
||||||
case ir.OTYPE:
|
case ir.OTYPE:
|
||||||
w.op(ir.OTYPE)
|
w.op(ir.OTYPE)
|
||||||
w.typ(n.Type)
|
w.typ(n.Type())
|
||||||
|
|
||||||
case ir.OTYPESW:
|
case ir.OTYPESW:
|
||||||
w.op(ir.OTYPESW)
|
w.op(ir.OTYPESW)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
var s *types.Sym
|
var s *types.Sym
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
if n.Left.Op != ir.ONONAME {
|
if n.Left().Op() != ir.ONONAME {
|
||||||
base.Fatalf("expected ONONAME, got %v", n.Left)
|
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.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:
|
// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
|
||||||
// should have been resolved by typechecking - handled by default case
|
// should have been resolved by typechecking - handled by default case
|
||||||
|
|
@ -1276,25 +1276,25 @@ func (w *exportWriter) expr(n *ir.Node) {
|
||||||
|
|
||||||
case ir.OPTRLIT:
|
case ir.OPTRLIT:
|
||||||
w.op(ir.OADDR)
|
w.op(ir.OADDR)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
|
|
||||||
case ir.OSTRUCTLIT:
|
case ir.OSTRUCTLIT:
|
||||||
w.op(ir.OSTRUCTLIT)
|
w.op(ir.OSTRUCTLIT)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.typ(n.Type)
|
w.typ(n.Type())
|
||||||
w.elemList(n.List) // special handling of field names
|
w.elemList(n.List()) // special handling of field names
|
||||||
|
|
||||||
case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
|
case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
|
||||||
w.op(ir.OCOMPLIT)
|
w.op(ir.OCOMPLIT)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.typ(n.Type)
|
w.typ(n.Type())
|
||||||
w.exprList(n.List)
|
w.exprList(n.List())
|
||||||
|
|
||||||
case ir.OKEY:
|
case ir.OKEY:
|
||||||
w.op(ir.OKEY)
|
w.op(ir.OKEY)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.exprsOrNil(n.Left, n.Right)
|
w.exprsOrNil(n.Left(), n.Right())
|
||||||
|
|
||||||
// case OSTRUCTKEY:
|
// case OSTRUCTKEY:
|
||||||
// unreachable - handled in case OSTRUCTLIT by elemList
|
// unreachable - handled in case OSTRUCTLIT by elemList
|
||||||
|
|
@ -1302,40 +1302,40 @@ func (w *exportWriter) expr(n *ir.Node) {
|
||||||
case ir.OCALLPART:
|
case ir.OCALLPART:
|
||||||
// An OCALLPART is an OXDOT before type checking.
|
// An OCALLPART is an OXDOT before type checking.
|
||||||
w.op(ir.OXDOT)
|
w.op(ir.OXDOT)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
// Right node should be ONAME
|
// 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:
|
case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH:
|
||||||
w.op(ir.OXDOT)
|
w.op(ir.OXDOT)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
w.selector(n.Sym)
|
w.selector(n.Sym())
|
||||||
|
|
||||||
case ir.ODOTTYPE, ir.ODOTTYPE2:
|
case ir.ODOTTYPE, ir.ODOTTYPE2:
|
||||||
w.op(ir.ODOTTYPE)
|
w.op(ir.ODOTTYPE)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
w.typ(n.Type)
|
w.typ(n.Type())
|
||||||
|
|
||||||
case ir.OINDEX, ir.OINDEXMAP:
|
case ir.OINDEX, ir.OINDEXMAP:
|
||||||
w.op(ir.OINDEX)
|
w.op(ir.OINDEX)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
w.expr(n.Right)
|
w.expr(n.Right())
|
||||||
|
|
||||||
case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR:
|
case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR:
|
||||||
w.op(ir.OSLICE)
|
w.op(ir.OSLICE)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
low, high, _ := n.SliceBounds()
|
low, high, _ := n.SliceBounds()
|
||||||
w.exprsOrNil(low, high)
|
w.exprsOrNil(low, high)
|
||||||
|
|
||||||
case ir.OSLICE3, ir.OSLICE3ARR:
|
case ir.OSLICE3, ir.OSLICE3ARR:
|
||||||
w.op(ir.OSLICE3)
|
w.op(ir.OSLICE3)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
low, high, max := n.SliceBounds()
|
low, high, max := n.SliceBounds()
|
||||||
w.exprsOrNil(low, high)
|
w.exprsOrNil(low, high)
|
||||||
w.expr(max)
|
w.expr(max)
|
||||||
|
|
@ -1343,25 +1343,25 @@ func (w *exportWriter) expr(n *ir.Node) {
|
||||||
case ir.OCOPY, ir.OCOMPLEX:
|
case ir.OCOPY, ir.OCOMPLEX:
|
||||||
// treated like other builtin calls (see e.g., OREAL)
|
// treated like other builtin calls (see e.g., OREAL)
|
||||||
w.op(op)
|
w.op(op)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
w.expr(n.Right)
|
w.expr(n.Right())
|
||||||
w.op(ir.OEND)
|
w.op(ir.OEND)
|
||||||
|
|
||||||
case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR:
|
case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR:
|
||||||
w.op(ir.OCONV)
|
w.op(ir.OCONV)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
w.typ(n.Type)
|
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:
|
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.op(op)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
w.op(ir.OEND)
|
w.op(ir.OEND)
|
||||||
} else {
|
} else {
|
||||||
w.exprList(n.List) // emits terminating OEND
|
w.exprList(n.List()) // emits terminating OEND
|
||||||
}
|
}
|
||||||
// only append() calls may contain '...' arguments
|
// only append() calls may contain '...' arguments
|
||||||
if op == ir.OAPPEND {
|
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:
|
case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
|
||||||
w.op(ir.OCALL)
|
w.op(ir.OCALL)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.stmtList(n.Ninit)
|
w.stmtList(n.Init())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
w.exprList(n.List)
|
w.exprList(n.List())
|
||||||
w.bool(n.IsDDD())
|
w.bool(n.IsDDD())
|
||||||
|
|
||||||
case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
|
case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
|
||||||
w.op(op) // must keep separate from OMAKE for importer
|
w.op(op) // must keep separate from OMAKE for importer
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.typ(n.Type)
|
w.typ(n.Type())
|
||||||
switch {
|
switch {
|
||||||
default:
|
default:
|
||||||
// empty list
|
// empty list
|
||||||
w.op(ir.OEND)
|
w.op(ir.OEND)
|
||||||
case n.List.Len() != 0: // pre-typecheck
|
case n.List().Len() != 0: // pre-typecheck
|
||||||
w.exprList(n.List) // emits terminating OEND
|
w.exprList(n.List()) // emits terminating OEND
|
||||||
case n.Right != nil:
|
case n.Right() != nil:
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
w.expr(n.Right)
|
w.expr(n.Right())
|
||||||
w.op(ir.OEND)
|
w.op(ir.OEND)
|
||||||
case n.Left != nil && (n.Op == ir.OMAKESLICE || !n.Left.Type.IsUntyped()):
|
case n.Left() != nil && (n.Op() == ir.OMAKESLICE || !n.Left().Type().IsUntyped()):
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
w.op(ir.OEND)
|
w.op(ir.OEND)
|
||||||
}
|
}
|
||||||
|
|
||||||
// unary expressions
|
// unary expressions
|
||||||
case ir.OPLUS, ir.ONEG, ir.OADDR, ir.OBITNOT, ir.ODEREF, ir.ONOT, ir.ORECV:
|
case ir.OPLUS, ir.ONEG, ir.OADDR, ir.OBITNOT, ir.ODEREF, ir.ONOT, ir.ORECV:
|
||||||
w.op(op)
|
w.op(op)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
|
|
||||||
// binary expressions
|
// binary expressions
|
||||||
case ir.OADD, ir.OAND, ir.OANDAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
|
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:
|
ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.OOROR, ir.ORSH, ir.OSEND, ir.OSUB, ir.OXOR:
|
||||||
w.op(op)
|
w.op(op)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left)
|
w.expr(n.Left())
|
||||||
w.expr(n.Right)
|
w.expr(n.Right())
|
||||||
|
|
||||||
case ir.OADDSTR:
|
case ir.OADDSTR:
|
||||||
w.op(ir.OADDSTR)
|
w.op(ir.OADDSTR)
|
||||||
w.pos(n.Pos)
|
w.pos(n.Pos())
|
||||||
w.exprList(n.List)
|
w.exprList(n.List())
|
||||||
|
|
||||||
case ir.ODCLCONST:
|
case ir.ODCLCONST:
|
||||||
// if exporting, DCLCONST should just be removed as its usage
|
// if exporting, DCLCONST should just be removed as its usage
|
||||||
|
|
@ -1422,7 +1422,7 @@ func (w *exportWriter) expr(n *ir.Node) {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
base.Fatalf("cannot export %v (%d) node\n"+
|
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) {
|
func (w *exportWriter) elemList(list ir.Nodes) {
|
||||||
w.uint64(uint64(list.Len()))
|
w.uint64(uint64(list.Len()))
|
||||||
for _, n := range list.Slice() {
|
for _, n := range list.Slice() {
|
||||||
w.selector(n.Sym)
|
w.selector(n.Sym())
|
||||||
w.expr(n.Left)
|
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
|
// PPARAM/PPARAMOUT, because we only want to include vargen in
|
||||||
// non-param names.
|
// non-param names.
|
||||||
var v int32
|
var v int32
|
||||||
if n.Class() == ir.PAUTO || (n.Class() == ir.PAUTOHEAP && n.Name.Param.Stackcopy == nil) {
|
if n.Class() == ir.PAUTO || (n.Class() == ir.PAUTOHEAP && n.Name().Param.Stackcopy == nil) {
|
||||||
v = n.Name.Vargen
|
v = n.Name().Vargen
|
||||||
}
|
}
|
||||||
|
|
||||||
w.localIdent(n.Sym, v)
|
w.localIdent(n.Sym(), v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *exportWriter) localIdent(s *types.Sym, v int32) {
|
func (w *exportWriter) localIdent(s *types.Sym, v int32) {
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func expandDecl(n *ir.Node) {
|
func expandDecl(n *ir.Node) {
|
||||||
if n.Op != ir.ONONAME {
|
if n.Op() != ir.ONONAME {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,7 +56,7 @@ func expandDecl(n *ir.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func expandInline(fn *ir.Node) {
|
func expandInline(fn *ir.Node) {
|
||||||
if fn.Func.Inl.Body != nil {
|
if fn.Func().Inl.Body != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,12 +69,12 @@ func expandInline(fn *ir.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func importReaderFor(n *ir.Node, importers map[*types.Sym]iimporterAndOffset) *importReader {
|
func importReaderFor(n *ir.Node, importers map[*types.Sym]iimporterAndOffset) *importReader {
|
||||||
x, ok := importers[n.Sym]
|
x, ok := importers[n.Sym()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return x.p.newReader(x.off, n.Sym.Pkg)
|
return x.p.newReader(x.off, n.Sym().Pkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
type intReader struct {
|
type intReader struct {
|
||||||
|
|
@ -282,8 +282,8 @@ func (r *importReader) setPkg() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *importReader) doDecl(n *ir.Node) {
|
func (r *importReader) doDecl(n *ir.Node) {
|
||||||
if n.Op != ir.ONONAME {
|
if n.Op() != ir.ONONAME {
|
||||||
base.Fatalf("doDecl: unexpected Op for %v: %v", n.Sym, n.Op)
|
base.Fatalf("doDecl: unexpected Op for %v: %v", n.Sym(), n.Op())
|
||||||
}
|
}
|
||||||
|
|
||||||
tag := r.byte()
|
tag := r.byte()
|
||||||
|
|
@ -293,24 +293,24 @@ func (r *importReader) doDecl(n *ir.Node) {
|
||||||
case 'A':
|
case 'A':
|
||||||
typ := r.typ()
|
typ := r.typ()
|
||||||
|
|
||||||
importalias(r.p.ipkg, pos, n.Sym, typ)
|
importalias(r.p.ipkg, pos, n.Sym(), typ)
|
||||||
|
|
||||||
case 'C':
|
case 'C':
|
||||||
typ := r.typ()
|
typ := r.typ()
|
||||||
val := r.value(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':
|
case 'F':
|
||||||
typ := r.signature(nil)
|
typ := r.signature(nil)
|
||||||
|
|
||||||
importfunc(r.p.ipkg, pos, n.Sym, typ)
|
importfunc(r.p.ipkg, pos, n.Sym(), typ)
|
||||||
r.funcExt(n)
|
r.funcExt(n)
|
||||||
|
|
||||||
case 'T':
|
case 'T':
|
||||||
// Types can be recursive. We need to setup a stub
|
// Types can be recursive. We need to setup a stub
|
||||||
// declaration before recursing.
|
// 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
|
// We also need to defer width calculations until
|
||||||
// after the underlying type has been assigned.
|
// after the underlying type has been assigned.
|
||||||
|
|
@ -332,7 +332,7 @@ func (r *importReader) doDecl(n *ir.Node) {
|
||||||
mtyp := r.signature(recv)
|
mtyp := r.signature(recv)
|
||||||
|
|
||||||
m := newfuncnamel(mpos, methodSym(recv.Type, msym), new(ir.Func))
|
m := newfuncnamel(mpos, methodSym(recv.Type, msym), new(ir.Func))
|
||||||
m.Type = mtyp
|
m.SetType(mtyp)
|
||||||
m.SetClass(ir.PFUNC)
|
m.SetClass(ir.PFUNC)
|
||||||
// methodSym already marked m.Sym as a function.
|
// methodSym already marked m.Sym as a function.
|
||||||
|
|
||||||
|
|
@ -350,7 +350,7 @@ func (r *importReader) doDecl(n *ir.Node) {
|
||||||
case 'V':
|
case 'V':
|
||||||
typ := r.typ()
|
typ := r.typ()
|
||||||
|
|
||||||
importvar(r.p.ipkg, pos, n.Sym, typ)
|
importvar(r.p.ipkg, pos, n.Sym(), typ)
|
||||||
r.varExt(n)
|
r.varExt(n)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -500,13 +500,13 @@ func (r *importReader) typ1() *types.Type {
|
||||||
// types. Therefore, this must be a package-scope
|
// types. Therefore, this must be a package-scope
|
||||||
// type.
|
// type.
|
||||||
n := ir.AsNode(r.qualifiedIdent().PkgDef())
|
n := ir.AsNode(r.qualifiedIdent().PkgDef())
|
||||||
if n.Op == ir.ONONAME {
|
if n.Op() == ir.ONONAME {
|
||||||
expandDecl(n)
|
expandDecl(n)
|
||||||
}
|
}
|
||||||
if n.Op != ir.OTYPE {
|
if n.Op() != ir.OTYPE {
|
||||||
base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op, n.Sym, n)
|
base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n)
|
||||||
}
|
}
|
||||||
return n.Type
|
return n.Type()
|
||||||
case pointerType:
|
case pointerType:
|
||||||
return types.NewPtr(r.typ())
|
return types.NewPtr(r.typ())
|
||||||
case sliceType:
|
case sliceType:
|
||||||
|
|
@ -636,27 +636,27 @@ func (r *importReader) byte() byte {
|
||||||
// Compiler-specific extensions.
|
// Compiler-specific extensions.
|
||||||
|
|
||||||
func (r *importReader) varExt(n *ir.Node) {
|
func (r *importReader) varExt(n *ir.Node) {
|
||||||
r.linkname(n.Sym)
|
r.linkname(n.Sym())
|
||||||
r.symIdx(n.Sym)
|
r.symIdx(n.Sym())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *importReader) funcExt(n *ir.Node) {
|
func (r *importReader) funcExt(n *ir.Node) {
|
||||||
r.linkname(n.Sym)
|
r.linkname(n.Sym())
|
||||||
r.symIdx(n.Sym)
|
r.symIdx(n.Sym())
|
||||||
|
|
||||||
// Escape analysis.
|
// Escape analysis.
|
||||||
for _, fs := range &types.RecvsParams {
|
for _, fs := range &types.RecvsParams {
|
||||||
for _, f := range fs(n.Type).FieldSlice() {
|
for _, f := range fs(n.Type()).FieldSlice() {
|
||||||
f.Note = r.string()
|
f.Note = r.string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inline body.
|
// Inline body.
|
||||||
if u := r.uint64(); u > 0 {
|
if u := r.uint64(); u > 0 {
|
||||||
n.Func.Inl = &ir.Inline{
|
n.Func().Inl = &ir.Inline{
|
||||||
Cost: int32(u - 1),
|
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)
|
var typeSymIdx = make(map[*types.Type][2]int64)
|
||||||
|
|
||||||
func (r *importReader) doInline(n *ir.Node) {
|
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)
|
base.Fatalf("%v already has inline body", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -712,15 +712,15 @@ func (r *importReader) doInline(n *ir.Node) {
|
||||||
// functions).
|
// functions).
|
||||||
body = []*ir.Node{}
|
body = []*ir.Node{}
|
||||||
}
|
}
|
||||||
n.Func.Inl.Body = body
|
n.Func().Inl.Body = body
|
||||||
|
|
||||||
importlist = append(importlist, n)
|
importlist = append(importlist, n)
|
||||||
|
|
||||||
if base.Flag.E > 0 && base.Flag.LowerM > 2 {
|
if base.Flag.E > 0 && base.Flag.LowerM > 2 {
|
||||||
if base.Flag.LowerM > 3 {
|
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 {
|
} 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
|
break
|
||||||
}
|
}
|
||||||
// OBLOCK nodes may be created when importing ODCL nodes - unpack them
|
// OBLOCK nodes may be created when importing ODCL nodes - unpack them
|
||||||
if n.Op == ir.OBLOCK {
|
if n.Op() == ir.OBLOCK {
|
||||||
list = append(list, n.List.Slice()...)
|
list = append(list, n.List().Slice()...)
|
||||||
} else {
|
} else {
|
||||||
list = append(list, n)
|
list = append(list, n)
|
||||||
}
|
}
|
||||||
|
|
@ -759,22 +759,22 @@ func (r *importReader) stmtList() []*ir.Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *importReader) caseList(sw *ir.Node) []*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())
|
cases := make([]*ir.Node, r.uint64())
|
||||||
for i := range cases {
|
for i := range cases {
|
||||||
cas := ir.NodAt(r.pos(), ir.OCASE, nil, nil)
|
cas := ir.NodAt(r.pos(), ir.OCASE, nil, nil)
|
||||||
cas.List.Set(r.stmtList())
|
cas.PtrList().Set(r.stmtList())
|
||||||
if namedTypeSwitch {
|
if namedTypeSwitch {
|
||||||
// Note: per-case variables will have distinct, dotted
|
// Note: per-case variables will have distinct, dotted
|
||||||
// names after import. That's okay: swt.go only needs
|
// names after import. That's okay: swt.go only needs
|
||||||
// Sym for diagnostics anyway.
|
// Sym for diagnostics anyway.
|
||||||
caseVar := ir.NewNameAt(cas.Pos, r.ident())
|
caseVar := ir.NewNameAt(cas.Pos(), r.ident())
|
||||||
declare(caseVar, dclcontext)
|
declare(caseVar, dclcontext)
|
||||||
cas.Rlist.Set1(caseVar)
|
cas.PtrRlist().Set1(caseVar)
|
||||||
caseVar.Name.Defn = sw.Left
|
caseVar.Name().Defn = sw.Left()
|
||||||
}
|
}
|
||||||
cas.Nbody.Set(r.stmtList())
|
cas.PtrBody().Set(r.stmtList())
|
||||||
cases[i] = cas
|
cases[i] = cas
|
||||||
}
|
}
|
||||||
return cases
|
return cases
|
||||||
|
|
@ -794,7 +794,7 @@ func (r *importReader) exprList() []*ir.Node {
|
||||||
|
|
||||||
func (r *importReader) expr() *ir.Node {
|
func (r *importReader) expr() *ir.Node {
|
||||||
n := r.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)
|
base.Fatalf("unexpected block node: %v", n)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
@ -821,7 +821,7 @@ func (r *importReader) node() *ir.Node {
|
||||||
n = ir.NewLiteral(r.value(typ))
|
n = ir.NewLiteral(r.value(typ))
|
||||||
}
|
}
|
||||||
n = npos(pos, n)
|
n = npos(pos, n)
|
||||||
n.Type = typ
|
n.SetType(typ)
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.ONONAME:
|
case ir.ONONAME:
|
||||||
|
|
@ -839,10 +839,10 @@ func (r *importReader) node() *ir.Node {
|
||||||
case ir.OTYPESW:
|
case ir.OTYPESW:
|
||||||
n := ir.NodAt(r.pos(), ir.OTYPESW, nil, nil)
|
n := ir.NodAt(r.pos(), ir.OTYPESW, nil, nil)
|
||||||
if s := r.ident(); s != nil {
|
if s := r.ident(); s != nil {
|
||||||
n.Left = npos(n.Pos, newnoname(s))
|
n.SetLeft(npos(n.Pos(), newnoname(s)))
|
||||||
}
|
}
|
||||||
right, _ := r.exprsOrNil()
|
right, _ := r.exprsOrNil()
|
||||||
n.Right = right
|
n.SetRight(right)
|
||||||
return n
|
return n
|
||||||
|
|
||||||
// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
|
// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
|
||||||
|
|
@ -859,7 +859,7 @@ func (r *importReader) node() *ir.Node {
|
||||||
savedlineno := base.Pos
|
savedlineno := base.Pos
|
||||||
base.Pos = r.pos()
|
base.Pos = r.pos()
|
||||||
n := ir.NodAt(base.Pos, ir.OCOMPLIT, nil, typenod(r.typ()))
|
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
|
base.Pos = savedlineno
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
|
@ -868,7 +868,7 @@ func (r *importReader) node() *ir.Node {
|
||||||
|
|
||||||
case ir.OCOMPLIT:
|
case ir.OCOMPLIT:
|
||||||
n := ir.NodAt(r.pos(), ir.OCOMPLIT, nil, typenod(r.typ()))
|
n := ir.NodAt(r.pos(), ir.OCOMPLIT, nil, typenod(r.typ()))
|
||||||
n.List.Set(r.exprList())
|
n.PtrList().Set(r.exprList())
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.OKEY:
|
case ir.OKEY:
|
||||||
|
|
@ -894,7 +894,7 @@ func (r *importReader) node() *ir.Node {
|
||||||
|
|
||||||
case ir.ODOTTYPE:
|
case ir.ODOTTYPE:
|
||||||
n := ir.NodAt(r.pos(), ir.ODOTTYPE, r.expr(), nil)
|
n := ir.NodAt(r.pos(), ir.ODOTTYPE, r.expr(), nil)
|
||||||
n.Type = r.typ()
|
n.SetType(r.typ())
|
||||||
return n
|
return n
|
||||||
|
|
||||||
// case OINDEX, OINDEXMAP, OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
|
// 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)
|
n := ir.NodAt(r.pos(), op, r.expr(), nil)
|
||||||
low, high := r.exprsOrNil()
|
low, high := r.exprsOrNil()
|
||||||
var max *ir.Node
|
var max *ir.Node
|
||||||
if n.Op.IsSlice3() {
|
if n.Op().IsSlice3() {
|
||||||
max = r.expr()
|
max = r.expr()
|
||||||
}
|
}
|
||||||
n.SetSliceBounds(low, high, max)
|
n.SetSliceBounds(low, high, max)
|
||||||
|
|
@ -918,12 +918,12 @@ func (r *importReader) node() *ir.Node {
|
||||||
|
|
||||||
case ir.OCONV:
|
case ir.OCONV:
|
||||||
n := ir.NodAt(r.pos(), ir.OCONV, r.expr(), nil)
|
n := ir.NodAt(r.pos(), ir.OCONV, r.expr(), nil)
|
||||||
n.Type = r.typ()
|
n.SetType(r.typ())
|
||||||
return n
|
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:
|
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 := npos(r.pos(), builtinCall(op))
|
||||||
n.List.Set(r.exprList())
|
n.PtrList().Set(r.exprList())
|
||||||
if op == ir.OAPPEND {
|
if op == ir.OAPPEND {
|
||||||
n.SetIsDDD(r.bool())
|
n.SetIsDDD(r.bool())
|
||||||
}
|
}
|
||||||
|
|
@ -934,16 +934,16 @@ func (r *importReader) node() *ir.Node {
|
||||||
|
|
||||||
case ir.OCALL:
|
case ir.OCALL:
|
||||||
n := ir.NodAt(r.pos(), ir.OCALL, nil, nil)
|
n := ir.NodAt(r.pos(), ir.OCALL, nil, nil)
|
||||||
n.Ninit.Set(r.stmtList())
|
n.PtrInit().Set(r.stmtList())
|
||||||
n.Left = r.expr()
|
n.SetLeft(r.expr())
|
||||||
n.List.Set(r.exprList())
|
n.PtrList().Set(r.exprList())
|
||||||
n.SetIsDDD(r.bool())
|
n.SetIsDDD(r.bool())
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
|
case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
|
||||||
n := npos(r.pos(), builtinCall(ir.OMAKE))
|
n := npos(r.pos(), builtinCall(ir.OMAKE))
|
||||||
n.List.Append(typenod(r.typ()))
|
n.PtrList().Append(typenod(r.typ()))
|
||||||
n.List.Append(r.exprList()...)
|
n.PtrList().Append(r.exprList()...)
|
||||||
return n
|
return n
|
||||||
|
|
||||||
// unary expressions
|
// unary expressions
|
||||||
|
|
@ -984,12 +984,12 @@ func (r *importReader) node() *ir.Node {
|
||||||
case ir.OASOP:
|
case ir.OASOP:
|
||||||
n := ir.NodAt(r.pos(), ir.OASOP, nil, nil)
|
n := ir.NodAt(r.pos(), ir.OASOP, nil, nil)
|
||||||
n.SetSubOp(r.op())
|
n.SetSubOp(r.op())
|
||||||
n.Left = r.expr()
|
n.SetLeft(r.expr())
|
||||||
if !r.bool() {
|
if !r.bool() {
|
||||||
n.Right = nodintconst(1)
|
n.SetRight(nodintconst(1))
|
||||||
n.SetImplicit(true)
|
n.SetImplicit(true)
|
||||||
} else {
|
} else {
|
||||||
n.Right = r.expr()
|
n.SetRight(r.expr())
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
|
@ -998,13 +998,13 @@ func (r *importReader) node() *ir.Node {
|
||||||
|
|
||||||
case ir.OAS2:
|
case ir.OAS2:
|
||||||
n := ir.NodAt(r.pos(), ir.OAS2, nil, nil)
|
n := ir.NodAt(r.pos(), ir.OAS2, nil, nil)
|
||||||
n.List.Set(r.exprList())
|
n.PtrList().Set(r.exprList())
|
||||||
n.Rlist.Set(r.exprList())
|
n.PtrRlist().Set(r.exprList())
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.ORETURN:
|
case ir.ORETURN:
|
||||||
n := ir.NodAt(r.pos(), ir.ORETURN, nil, nil)
|
n := ir.NodAt(r.pos(), ir.ORETURN, nil, nil)
|
||||||
n.List.Set(r.exprList())
|
n.PtrList().Set(r.exprList())
|
||||||
return n
|
return n
|
||||||
|
|
||||||
// case ORETJMP:
|
// case ORETJMP:
|
||||||
|
|
@ -1015,34 +1015,34 @@ func (r *importReader) node() *ir.Node {
|
||||||
|
|
||||||
case ir.OIF:
|
case ir.OIF:
|
||||||
n := ir.NodAt(r.pos(), ir.OIF, nil, nil)
|
n := ir.NodAt(r.pos(), ir.OIF, nil, nil)
|
||||||
n.Ninit.Set(r.stmtList())
|
n.PtrInit().Set(r.stmtList())
|
||||||
n.Left = r.expr()
|
n.SetLeft(r.expr())
|
||||||
n.Nbody.Set(r.stmtList())
|
n.PtrBody().Set(r.stmtList())
|
||||||
n.Rlist.Set(r.stmtList())
|
n.PtrRlist().Set(r.stmtList())
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.OFOR:
|
case ir.OFOR:
|
||||||
n := ir.NodAt(r.pos(), ir.OFOR, nil, nil)
|
n := ir.NodAt(r.pos(), ir.OFOR, nil, nil)
|
||||||
n.Ninit.Set(r.stmtList())
|
n.PtrInit().Set(r.stmtList())
|
||||||
left, right := r.exprsOrNil()
|
left, right := r.exprsOrNil()
|
||||||
n.Left = left
|
n.SetLeft(left)
|
||||||
n.Right = right
|
n.SetRight(right)
|
||||||
n.Nbody.Set(r.stmtList())
|
n.PtrBody().Set(r.stmtList())
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.ORANGE:
|
case ir.ORANGE:
|
||||||
n := ir.NodAt(r.pos(), ir.ORANGE, nil, nil)
|
n := ir.NodAt(r.pos(), ir.ORANGE, nil, nil)
|
||||||
n.List.Set(r.stmtList())
|
n.PtrList().Set(r.stmtList())
|
||||||
n.Right = r.expr()
|
n.SetRight(r.expr())
|
||||||
n.Nbody.Set(r.stmtList())
|
n.PtrBody().Set(r.stmtList())
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.OSELECT, ir.OSWITCH:
|
case ir.OSELECT, ir.OSWITCH:
|
||||||
n := ir.NodAt(r.pos(), op, nil, nil)
|
n := ir.NodAt(r.pos(), op, nil, nil)
|
||||||
n.Ninit.Set(r.stmtList())
|
n.PtrInit().Set(r.stmtList())
|
||||||
left, _ := r.exprsOrNil()
|
left, _ := r.exprsOrNil()
|
||||||
n.Left = left
|
n.SetLeft(left)
|
||||||
n.List.Set(r.caseList(n))
|
n.PtrList().Set(r.caseList(n))
|
||||||
return n
|
return n
|
||||||
|
|
||||||
// case OCASE:
|
// case OCASE:
|
||||||
|
|
@ -1056,7 +1056,7 @@ func (r *importReader) node() *ir.Node {
|
||||||
pos := r.pos()
|
pos := r.pos()
|
||||||
left, _ := r.exprsOrNil()
|
left, _ := r.exprsOrNil()
|
||||||
if left != nil {
|
if left != nil {
|
||||||
left = NewName(left.Sym)
|
left = NewName(left.Sym())
|
||||||
}
|
}
|
||||||
return ir.NodAt(pos, op, left, nil)
|
return ir.NodAt(pos, op, left, nil)
|
||||||
|
|
||||||
|
|
@ -1065,7 +1065,7 @@ func (r *importReader) node() *ir.Node {
|
||||||
|
|
||||||
case ir.OGOTO, ir.OLABEL:
|
case ir.OGOTO, ir.OLABEL:
|
||||||
n := ir.NodAt(r.pos(), op, nil, nil)
|
n := ir.NodAt(r.pos(), op, nil, nil)
|
||||||
n.Sym = lookup(r.string())
|
n.SetSym(lookup(r.string()))
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.OEND:
|
case ir.OEND:
|
||||||
|
|
|
||||||
|
|
@ -46,16 +46,16 @@ func fninit(n []*ir.Node) {
|
||||||
|
|
||||||
// Make a function that contains all the initialization statements.
|
// Make a function that contains all the initialization statements.
|
||||||
if len(nf) > 0 {
|
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")
|
initializers := lookup("init")
|
||||||
fn := dclfunc(initializers, ir.Nod(ir.OTFUNC, nil, nil))
|
fn := dclfunc(initializers, ir.Nod(ir.OTFUNC, nil, nil))
|
||||||
for _, dcl := range initTodo.Func.Dcl {
|
for _, dcl := range initTodo.Func().Dcl {
|
||||||
dcl.Name.Curfn = fn
|
dcl.Name().Curfn = fn
|
||||||
}
|
}
|
||||||
fn.Func.Dcl = append(fn.Func.Dcl, initTodo.Func.Dcl...)
|
fn.Func().Dcl = append(fn.Func().Dcl, initTodo.Func().Dcl...)
|
||||||
initTodo.Func.Dcl = nil
|
initTodo.Func().Dcl = nil
|
||||||
|
|
||||||
fn.Nbody.Set(nf)
|
fn.PtrBody().Set(nf)
|
||||||
funcbody()
|
funcbody()
|
||||||
|
|
||||||
fn = typecheck(fn, ctxStmt)
|
fn = typecheck(fn, ctxStmt)
|
||||||
|
|
@ -65,7 +65,7 @@ func fninit(n []*ir.Node) {
|
||||||
xtop = append(xtop, fn)
|
xtop = append(xtop, fn)
|
||||||
fns = append(fns, initializers.Linksym())
|
fns = append(fns, initializers.Linksym())
|
||||||
}
|
}
|
||||||
if initTodo.Func.Dcl != nil {
|
if initTodo.Func().Dcl != nil {
|
||||||
// We only generate temps using initTodo if there
|
// We only generate temps using initTodo if there
|
||||||
// are package-scope initialization statements, so
|
// are package-scope initialization statements, so
|
||||||
// something's weird if we get here.
|
// something's weird if we get here.
|
||||||
|
|
@ -76,9 +76,9 @@ func fninit(n []*ir.Node) {
|
||||||
// Record user init functions.
|
// Record user init functions.
|
||||||
for i := 0; i < renameinitgen; i++ {
|
for i := 0; i < renameinitgen; i++ {
|
||||||
s := lookupN("init.", 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.
|
// 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
|
continue
|
||||||
}
|
}
|
||||||
fns = append(fns, s.Linksym())
|
fns = append(fns, s.Linksym())
|
||||||
|
|
@ -91,7 +91,7 @@ func fninit(n []*ir.Node) {
|
||||||
// Make an .inittask structure.
|
// Make an .inittask structure.
|
||||||
sym := lookup(".inittask")
|
sym := lookup(".inittask")
|
||||||
nn := NewName(sym)
|
nn := NewName(sym)
|
||||||
nn.Type = types.Types[types.TUINT8] // fake type
|
nn.SetType(types.Types[types.TUINT8]) // fake type
|
||||||
nn.SetClass(ir.PEXTERN)
|
nn.SetClass(ir.PEXTERN)
|
||||||
sym.Def = ir.AsTypesNode(nn)
|
sym.Def = ir.AsTypesNode(nn)
|
||||||
exportsym(nn)
|
exportsym(nn)
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ func initOrder(l []*ir.Node) []*ir.Node {
|
||||||
|
|
||||||
// Process all package-level assignment in declaration order.
|
// Process all package-level assignment in declaration order.
|
||||||
for _, n := range l {
|
for _, n := range l {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.OAS, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
|
case ir.OAS, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
|
||||||
o.processAssign(n)
|
o.processAssign(n)
|
||||||
o.flushReady(s.staticInit)
|
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
|
// Check that all assignments are now Done; if not, there must
|
||||||
// have been a dependency cycle.
|
// have been a dependency cycle.
|
||||||
for _, n := range l {
|
for _, n := range l {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.OAS, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
|
case ir.OAS, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
|
||||||
if n.Initorder() != InitDone {
|
if n.Initorder() != InitDone {
|
||||||
// If there have already been errors
|
// If there have already been errors
|
||||||
|
|
@ -126,27 +126,27 @@ func initOrder(l []*ir.Node) []*ir.Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *InitOrder) processAssign(n *ir.Node) {
|
func (o *InitOrder) processAssign(n *ir.Node) {
|
||||||
if n.Initorder() != InitNotStarted || n.Xoffset != types.BADWIDTH {
|
if n.Initorder() != InitNotStarted || n.Offset() != types.BADWIDTH {
|
||||||
base.Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Xoffset)
|
base.Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Offset())
|
||||||
}
|
}
|
||||||
|
|
||||||
n.SetInitorder(InitPending)
|
n.SetInitorder(InitPending)
|
||||||
n.Xoffset = 0
|
n.SetOffset(0)
|
||||||
|
|
||||||
// Compute number of variable dependencies and build the
|
// Compute number of variable dependencies and build the
|
||||||
// inverse dependency ("blocking") graph.
|
// inverse dependency ("blocking") graph.
|
||||||
for dep := range collectDeps(n, true) {
|
for dep := range collectDeps(n, true) {
|
||||||
defn := dep.Name.Defn
|
defn := dep.Name().Defn
|
||||||
// Skip dependencies on functions (PFUNC) and
|
// Skip dependencies on functions (PFUNC) and
|
||||||
// variables already initialized (InitDone).
|
// variables already initialized (InitDone).
|
||||||
if dep.Class() != ir.PEXTERN || defn.Initorder() == InitDone {
|
if dep.Class() != ir.PEXTERN || defn.Initorder() == InitDone {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
n.Xoffset = n.Xoffset + 1
|
n.SetOffset(n.Offset() + 1)
|
||||||
o.blocking[defn] = append(o.blocking[defn], n)
|
o.blocking[defn] = append(o.blocking[defn], n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Xoffset == 0 {
|
if n.Offset() == 0 {
|
||||||
heap.Push(&o.ready, n)
|
heap.Push(&o.ready, n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -157,20 +157,20 @@ func (o *InitOrder) processAssign(n *ir.Node) {
|
||||||
func (o *InitOrder) flushReady(initialize func(*ir.Node)) {
|
func (o *InitOrder) flushReady(initialize func(*ir.Node)) {
|
||||||
for o.ready.Len() != 0 {
|
for o.ready.Len() != 0 {
|
||||||
n := heap.Pop(&o.ready).(*ir.Node)
|
n := heap.Pop(&o.ready).(*ir.Node)
|
||||||
if n.Initorder() != InitPending || n.Xoffset != 0 {
|
if n.Initorder() != InitPending || n.Offset() != 0 {
|
||||||
base.Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Xoffset)
|
base.Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Offset())
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize(n)
|
initialize(n)
|
||||||
n.SetInitorder(InitDone)
|
n.SetInitorder(InitDone)
|
||||||
n.Xoffset = types.BADWIDTH
|
n.SetOffset(types.BADWIDTH)
|
||||||
|
|
||||||
blocked := o.blocking[n]
|
blocked := o.blocking[n]
|
||||||
delete(o.blocking, n)
|
delete(o.blocking, n)
|
||||||
|
|
||||||
for _, m := range blocked {
|
for _, m := range blocked {
|
||||||
m.Xoffset = m.Xoffset - 1
|
m.SetOffset(m.Offset() - 1)
|
||||||
if m.Xoffset == 0 {
|
if m.Offset() == 0 {
|
||||||
heap.Push(&o.ready, m)
|
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
|
// There might be multiple loops involving n; by sorting
|
||||||
// references, we deterministically pick the one reported.
|
// references, we deterministically pick the one reported.
|
||||||
refers := collectDeps(n.Name.Defn, false).Sorted(func(ni, nj *ir.Node) bool {
|
refers := collectDeps(n.Name().Defn, false).Sorted(func(ni, nj *ir.Node) bool {
|
||||||
return ni.Pos.Before(nj.Pos)
|
return ni.Pos().Before(nj.Pos())
|
||||||
})
|
})
|
||||||
|
|
||||||
*path = append(*path, n)
|
*path = append(*path, n)
|
||||||
for _, ref := range refers {
|
for _, ref := range refers {
|
||||||
// Short-circuit variables that were initialized.
|
// 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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,7 +220,7 @@ func reportInitLoopAndExit(l []*ir.Node) {
|
||||||
// the start.
|
// the start.
|
||||||
i := -1
|
i := -1
|
||||||
for j, n := range l {
|
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
|
i = j
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -242,7 +242,7 @@ func reportInitLoopAndExit(l []*ir.Node) {
|
||||||
}
|
}
|
||||||
fmt.Fprintf(&msg, "\t%v: %v", ir.Line(l[0]), l[0])
|
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()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -252,15 +252,15 @@ func reportInitLoopAndExit(l []*ir.Node) {
|
||||||
// upon functions (but not variables).
|
// upon functions (but not variables).
|
||||||
func collectDeps(n *ir.Node, transitive bool) ir.NodeSet {
|
func collectDeps(n *ir.Node, transitive bool) ir.NodeSet {
|
||||||
d := initDeps{transitive: transitive}
|
d := initDeps{transitive: transitive}
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.OAS:
|
case ir.OAS:
|
||||||
d.inspect(n.Right)
|
d.inspect(n.Right())
|
||||||
case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
|
case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
|
||||||
d.inspect(n.Right)
|
d.inspect(n.Right())
|
||||||
case ir.ODCLFUNC:
|
case ir.ODCLFUNC:
|
||||||
d.inspectList(n.Nbody)
|
d.inspectList(n.Body())
|
||||||
default:
|
default:
|
||||||
base.Fatalf("unexpected Op: %v", n.Op)
|
base.Fatalf("unexpected Op: %v", n.Op())
|
||||||
}
|
}
|
||||||
return d.seen
|
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
|
// visit calls foundDep on any package-level functions or variables
|
||||||
// referenced by n, if any.
|
// referenced by n, if any.
|
||||||
func (d *initDeps) visit(n *ir.Node) bool {
|
func (d *initDeps) visit(n *ir.Node) bool {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.OMETHEXPR:
|
case ir.OMETHEXPR:
|
||||||
d.foundDep(methodExprName(n))
|
d.foundDep(methodExprName(n))
|
||||||
return false
|
return false
|
||||||
|
|
@ -288,7 +288,7 @@ func (d *initDeps) visit(n *ir.Node) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OCLOSURE:
|
case ir.OCLOSURE:
|
||||||
d.inspectList(n.Func.Decl.Nbody)
|
d.inspectList(n.Func().Decl.Body())
|
||||||
|
|
||||||
case ir.ODOTMETH, ir.OCALLPART:
|
case ir.ODOTMETH, ir.OCALLPART:
|
||||||
d.foundDep(methodExprName(n))
|
d.foundDep(methodExprName(n))
|
||||||
|
|
@ -308,7 +308,7 @@ func (d *initDeps) foundDep(n *ir.Node) {
|
||||||
|
|
||||||
// Names without definitions aren't interesting as far as
|
// Names without definitions aren't interesting as far as
|
||||||
// initialization ordering goes.
|
// initialization ordering goes.
|
||||||
if n.Name.Defn == nil {
|
if n.Name().Defn == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -317,7 +317,7 @@ func (d *initDeps) foundDep(n *ir.Node) {
|
||||||
}
|
}
|
||||||
d.seen.Add(n)
|
d.seen.Add(n)
|
||||||
if d.transitive && n.Class() == ir.PFUNC {
|
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.
|
// but both OAS nodes use the "=" token's position as their Pos.
|
||||||
type declOrder []*ir.Node
|
type declOrder []*ir.Node
|
||||||
|
|
||||||
func (s declOrder) Len() int { return len(s) }
|
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) Less(i, j int) bool {
|
||||||
func (s declOrder) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
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) Push(x interface{}) { *s = append(*s, x.(*ir.Node)) }
|
||||||
func (s *declOrder) Pop() interface{} {
|
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
|
// firstLHS returns the first expression on the left-hand side of
|
||||||
// assignment n.
|
// assignment n.
|
||||||
func firstLHS(n *ir.Node) *ir.Node {
|
func firstLHS(n *ir.Node) *ir.Node {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.OAS:
|
case ir.OAS:
|
||||||
return n.Left
|
return n.Left()
|
||||||
case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2RECV, ir.OAS2MAPR:
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -253,7 +253,7 @@ func Main(archInit func(*Arch)) {
|
||||||
timings.Start("fe", "typecheck", "top1")
|
timings.Start("fe", "typecheck", "top1")
|
||||||
for i := 0; i < len(xtop); i++ {
|
for i := 0; i < len(xtop); i++ {
|
||||||
n := 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)
|
xtop[i] = typecheck(n, ctxStmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +265,7 @@ func Main(archInit func(*Arch)) {
|
||||||
timings.Start("fe", "typecheck", "top2")
|
timings.Start("fe", "typecheck", "top2")
|
||||||
for i := 0; i < len(xtop); i++ {
|
for i := 0; i < len(xtop); i++ {
|
||||||
n := 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)
|
xtop[i] = typecheck(n, ctxStmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -276,14 +276,14 @@ func Main(archInit func(*Arch)) {
|
||||||
var fcount int64
|
var fcount int64
|
||||||
for i := 0; i < len(xtop); i++ {
|
for i := 0; i < len(xtop); i++ {
|
||||||
n := xtop[i]
|
n := xtop[i]
|
||||||
if n.Op == ir.ODCLFUNC {
|
if n.Op() == ir.ODCLFUNC {
|
||||||
Curfn = n
|
Curfn = n
|
||||||
decldepth = 1
|
decldepth = 1
|
||||||
errorsBefore := base.Errors()
|
errorsBefore := base.Errors()
|
||||||
typecheckslice(Curfn.Nbody.Slice(), ctxStmt)
|
typecheckslice(Curfn.Body().Slice(), ctxStmt)
|
||||||
checkreturn(Curfn)
|
checkreturn(Curfn)
|
||||||
if base.Errors() > errorsBefore {
|
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,
|
// Now that we've checked whether n terminates,
|
||||||
// we can eliminate some obviously dead code.
|
// we can eliminate some obviously dead code.
|
||||||
|
|
@ -306,7 +306,7 @@ func Main(archInit func(*Arch)) {
|
||||||
// because variables captured by value do not escape.
|
// because variables captured by value do not escape.
|
||||||
timings.Start("fe", "capturevars")
|
timings.Start("fe", "capturevars")
|
||||||
for _, n := range xtop {
|
for _, n := range xtop {
|
||||||
if n.Op == ir.ODCLFUNC && n.Func.OClosure != nil {
|
if n.Op() == ir.ODCLFUNC && n.Func().OClosure != nil {
|
||||||
Curfn = n
|
Curfn = n
|
||||||
capturevars(n)
|
capturevars(n)
|
||||||
}
|
}
|
||||||
|
|
@ -321,7 +321,7 @@ func Main(archInit func(*Arch)) {
|
||||||
// Typecheck imported function bodies if Debug.l > 1,
|
// Typecheck imported function bodies if Debug.l > 1,
|
||||||
// otherwise lazily when used or re-exported.
|
// otherwise lazily when used or re-exported.
|
||||||
for _, n := range importlist {
|
for _, n := range importlist {
|
||||||
if n.Func.Inl != nil {
|
if n.Func().Inl != nil {
|
||||||
typecheckinl(n)
|
typecheckinl(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -340,7 +340,7 @@ func Main(archInit func(*Arch)) {
|
||||||
caninl(n)
|
caninl(n)
|
||||||
} else {
|
} else {
|
||||||
if base.Flag.LowerM > 1 {
|
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)
|
inlcalls(n)
|
||||||
|
|
@ -349,7 +349,7 @@ func Main(archInit func(*Arch)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, n := range xtop {
|
for _, n := range xtop {
|
||||||
if n.Op == ir.ODCLFUNC {
|
if n.Op() == ir.ODCLFUNC {
|
||||||
devirtualize(n)
|
devirtualize(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -379,7 +379,7 @@ func Main(archInit func(*Arch)) {
|
||||||
// before walk reaches a call of a closure.
|
// before walk reaches a call of a closure.
|
||||||
timings.Start("fe", "xclosures")
|
timings.Start("fe", "xclosures")
|
||||||
for _, n := range xtop {
|
for _, n := range xtop {
|
||||||
if n.Op == ir.ODCLFUNC && n.Func.OClosure != nil {
|
if n.Op() == ir.ODCLFUNC && n.Func().OClosure != nil {
|
||||||
Curfn = n
|
Curfn = n
|
||||||
transformclosure(n)
|
transformclosure(n)
|
||||||
}
|
}
|
||||||
|
|
@ -402,7 +402,7 @@ func Main(archInit func(*Arch)) {
|
||||||
fcount = 0
|
fcount = 0
|
||||||
for i := 0; i < len(xtop); i++ {
|
for i := 0; i < len(xtop); i++ {
|
||||||
n := xtop[i]
|
n := xtop[i]
|
||||||
if n.Op == ir.ODCLFUNC {
|
if n.Op() == ir.ODCLFUNC {
|
||||||
funccompile(n)
|
funccompile(n)
|
||||||
fcount++
|
fcount++
|
||||||
}
|
}
|
||||||
|
|
@ -430,7 +430,7 @@ func Main(archInit func(*Arch)) {
|
||||||
// Phase 9: Check external declarations.
|
// Phase 9: Check external declarations.
|
||||||
timings.Start("be", "externaldcls")
|
timings.Start("be", "externaldcls")
|
||||||
for i, n := range externdcl {
|
for i, n := range externdcl {
|
||||||
if n.Op == ir.ONAME {
|
if n.Op() == ir.ONAME {
|
||||||
externdcl[i] = typecheck(externdcl[i], ctxExpr)
|
externdcl[i] = typecheck(externdcl[i], ctxExpr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -484,7 +484,7 @@ func Main(archInit func(*Arch)) {
|
||||||
func numNonClosures(list []*ir.Node) int {
|
func numNonClosures(list []*ir.Node) int {
|
||||||
count := 0
|
count := 0
|
||||||
for _, n := range list {
|
for _, n := range list {
|
||||||
if n.Func.OClosure == nil {
|
if n.Func().OClosure == nil {
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -949,14 +949,14 @@ func clearImports() {
|
||||||
if n == nil {
|
if n == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if n.Op == ir.OPACK {
|
if n.Op() == ir.OPACK {
|
||||||
// throw away top-level package name left over
|
// throw away top-level package name left over
|
||||||
// from previous file.
|
// from previous file.
|
||||||
// leave s->block set to cause redeclaration
|
// leave s->block set to cause redeclaration
|
||||||
// errors if a conflicting top-level name is
|
// errors if a conflicting top-level name is
|
||||||
// introduced by a different file.
|
// introduced by a different file.
|
||||||
if !n.Name.Used() && base.SyntaxErrors() == 0 {
|
if !n.Name().Used() && base.SyntaxErrors() == 0 {
|
||||||
unused = append(unused, importedPkg{n.Pos, n.Name.Pkg.Path, s.Name})
|
unused = append(unused, importedPkg{n.Pos(), n.Name().Pkg.Path, s.Name})
|
||||||
}
|
}
|
||||||
s.Def = nil
|
s.Def = nil
|
||||||
continue
|
continue
|
||||||
|
|
@ -964,9 +964,9 @@ func clearImports() {
|
||||||
if IsAlias(s) {
|
if IsAlias(s) {
|
||||||
// throw away top-level name left over
|
// throw away top-level name left over
|
||||||
// from previous import . "x"
|
// from previous import . "x"
|
||||||
if n.Name != nil && n.Name.Pack != nil && !n.Name.Pack.Name.Used() && base.SyntaxErrors() == 0 {
|
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, ""})
|
unused = append(unused, importedPkg{n.Name().Pack.Pos(), n.Name().Pack.Name().Pkg.Path, ""})
|
||||||
n.Name.Pack.Name.SetUsed(true)
|
n.Name().Pack.Name().SetUsed(true)
|
||||||
}
|
}
|
||||||
s.Def = nil
|
s.Def = nil
|
||||||
continue
|
continue
|
||||||
|
|
@ -980,7 +980,7 @@ func clearImports() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsAlias(sym *types.Sym) bool {
|
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
|
// recordFlags records the specified command-line flags to be placed
|
||||||
|
|
|
||||||
|
|
@ -162,10 +162,10 @@ func (p *noder) funcBody(fn *ir.Node, block *syntax.BlockStmt) {
|
||||||
if body == nil {
|
if body == nil {
|
||||||
body = []*ir.Node{ir.Nod(ir.OEMPTY, nil, nil)}
|
body = []*ir.Node{ir.Nod(ir.OEMPTY, nil, nil)}
|
||||||
}
|
}
|
||||||
fn.Nbody.Set(body)
|
fn.PtrBody().Set(body)
|
||||||
|
|
||||||
base.Pos = p.makeXPos(block.Rbrace)
|
base.Pos = p.makeXPos(block.Rbrace)
|
||||||
fn.Func.Endlineno = base.Pos
|
fn.Func().Endlineno = base.Pos
|
||||||
}
|
}
|
||||||
|
|
||||||
funcbody()
|
funcbody()
|
||||||
|
|
@ -176,9 +176,9 @@ func (p *noder) openScope(pos syntax.Pos) {
|
||||||
types.Markdcl()
|
types.Markdcl()
|
||||||
|
|
||||||
if trackScopes {
|
if trackScopes {
|
||||||
Curfn.Func.Parents = append(Curfn.Func.Parents, p.scope)
|
Curfn.Func().Parents = append(Curfn.Func().Parents, p.scope)
|
||||||
p.scopeVars = append(p.scopeVars, len(Curfn.Func.Dcl))
|
p.scopeVars = append(p.scopeVars, len(Curfn.Func().Dcl))
|
||||||
p.scope = ir.ScopeID(len(Curfn.Func.Parents))
|
p.scope = ir.ScopeID(len(Curfn.Func().Parents))
|
||||||
|
|
||||||
p.markScope(pos)
|
p.markScope(pos)
|
||||||
}
|
}
|
||||||
|
|
@ -191,29 +191,29 @@ func (p *noder) closeScope(pos syntax.Pos) {
|
||||||
if trackScopes {
|
if trackScopes {
|
||||||
scopeVars := p.scopeVars[len(p.scopeVars)-1]
|
scopeVars := p.scopeVars[len(p.scopeVars)-1]
|
||||||
p.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.
|
// 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")
|
base.Fatalf("scope tracking inconsistency, no variables declared but scopes were not retracted")
|
||||||
}
|
}
|
||||||
|
|
||||||
p.scope = Curfn.Func.Parents[p.scope-1]
|
p.scope = Curfn.Func().Parents[p.scope-1]
|
||||||
Curfn.Func.Parents = Curfn.Func.Parents[:len(Curfn.Func.Parents)-1]
|
Curfn.Func().Parents = Curfn.Func().Parents[:len(Curfn.Func().Parents)-1]
|
||||||
|
|
||||||
nmarks := len(Curfn.Func.Marks)
|
nmarks := len(Curfn.Func().Marks)
|
||||||
Curfn.Func.Marks[nmarks-1].Scope = p.scope
|
Curfn.Func().Marks[nmarks-1].Scope = p.scope
|
||||||
prevScope := ir.ScopeID(0)
|
prevScope := ir.ScopeID(0)
|
||||||
if nmarks >= 2 {
|
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 {
|
if Curfn.Func().Marks[nmarks-1].Scope == prevScope {
|
||||||
Curfn.Func.Marks = Curfn.Func.Marks[:nmarks-1]
|
Curfn.Func().Marks = Curfn.Func().Marks[:nmarks-1]
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
p.scope = Curfn.Func.Parents[p.scope-1]
|
p.scope = Curfn.Func().Parents[p.scope-1]
|
||||||
|
|
||||||
p.markScope(pos)
|
p.markScope(pos)
|
||||||
}
|
}
|
||||||
|
|
@ -221,10 +221,10 @@ func (p *noder) closeScope(pos syntax.Pos) {
|
||||||
|
|
||||||
func (p *noder) markScope(pos syntax.Pos) {
|
func (p *noder) markScope(pos syntax.Pos) {
|
||||||
xpos := p.makeXPos(pos)
|
xpos := p.makeXPos(pos)
|
||||||
if i := len(Curfn.Func.Marks); i > 0 && Curfn.Func.Marks[i-1].Pos == xpos {
|
if i := len(Curfn.Func().Marks); i > 0 && Curfn.Func().Marks[i-1].Pos == xpos {
|
||||||
Curfn.Func.Marks[i-1].Scope = p.scope
|
Curfn.Func().Marks[i-1].Scope = p.scope
|
||||||
} else {
|
} 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 := p.nod(imp, ir.OPACK, nil, nil)
|
||||||
pack.Sym = my
|
pack.SetSym(my)
|
||||||
pack.Name.Pkg = ipkg
|
pack.Name().Pkg = ipkg
|
||||||
|
|
||||||
switch my.Name {
|
switch my.Name {
|
||||||
case ".":
|
case ".":
|
||||||
importdot(ipkg, pack)
|
importdot(ipkg, pack)
|
||||||
return
|
return
|
||||||
case "init":
|
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
|
return
|
||||||
case "_":
|
case "_":
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if my.Def != nil {
|
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.Def = ir.AsTypesNode(pack)
|
||||||
my.Lastlineno = pack.Pos
|
my.Lastlineno = pack.Pos()
|
||||||
my.Block = 1 // at top level
|
my.Block = 1 // at top level
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -452,14 +452,14 @@ func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*ir.Node {
|
||||||
}
|
}
|
||||||
v := values[i]
|
v := values[i]
|
||||||
if decl.Values == nil {
|
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)
|
declare(n, dclcontext)
|
||||||
|
|
||||||
n.Name.Param.Ntype = typ
|
n.Name().Param.Ntype = typ
|
||||||
n.Name.Defn = v
|
n.Name().Defn = v
|
||||||
n.SetIota(cs.iota)
|
n.SetIota(cs.iota)
|
||||||
|
|
||||||
nn = append(nn, p.nod(decl, ir.ODCLCONST, n, nil))
|
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 {
|
func (p *noder) typeDecl(decl *syntax.TypeDecl) *ir.Node {
|
||||||
n := p.declName(decl.Name)
|
n := p.declName(decl.Name)
|
||||||
n.Op = ir.OTYPE
|
n.SetOp(ir.OTYPE)
|
||||||
declare(n, dclcontext)
|
declare(n, dclcontext)
|
||||||
|
|
||||||
// decl.Type may be nil but in that case we got a syntax error during parsing
|
// decl.Type may be nil but in that case we got a syntax error during parsing
|
||||||
typ := p.typeExprOrNil(decl.Type)
|
typ := p.typeExprOrNil(decl.Type)
|
||||||
|
|
||||||
param := n.Name.Param
|
param := n.Name().Param
|
||||||
param.Ntype = typ
|
param.Ntype = typ
|
||||||
param.SetAlias(decl.Alias)
|
param.SetAlias(decl.Alias)
|
||||||
if pragma, ok := decl.Pragma.(*Pragma); ok {
|
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)
|
nod := p.nod(decl, ir.ODCLTYPE, n, nil)
|
||||||
if param.Alias() && !langSupported(1, 9, ir.LocalPkg) {
|
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
|
return nod
|
||||||
}
|
}
|
||||||
|
|
@ -510,7 +510,7 @@ func (p *noder) declNames(names []*syntax.Name) []*ir.Node {
|
||||||
|
|
||||||
func (p *noder) declName(name *syntax.Name) *ir.Node {
|
func (p *noder) declName(name *syntax.Name) *ir.Node {
|
||||||
n := dclname(p.name(name))
|
n := dclname(p.name(name))
|
||||||
n.Pos = p.pos(name)
|
n.SetPos(p.pos(name))
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -522,43 +522,43 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *ir.Node {
|
||||||
if fun.Recv == nil {
|
if fun.Recv == nil {
|
||||||
if name.Name == "init" {
|
if name.Name == "init" {
|
||||||
name = renameinit()
|
name = renameinit()
|
||||||
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
if t.List().Len() > 0 || t.Rlist().Len() > 0 {
|
||||||
base.ErrorfAt(f.Pos, "func init must have no arguments and no return values")
|
base.ErrorfAt(f.Pos(), "func init must have no arguments and no return values")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ir.LocalPkg.Name == "main" && name.Name == "main" {
|
if ir.LocalPkg.Name == "main" && name.Name == "main" {
|
||||||
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
if t.List().Len() > 0 || t.Rlist().Len() > 0 {
|
||||||
base.ErrorfAt(f.Pos, "func main must have no arguments and no return values")
|
base.ErrorfAt(f.Pos(), "func main must have no arguments and no return values")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
f.Func.Shortname = name
|
f.Func().Shortname = name
|
||||||
name = ir.BlankNode.Sym // filled in by typecheckfunc
|
name = ir.BlankNode.Sym() // filled in by typecheckfunc
|
||||||
}
|
}
|
||||||
|
|
||||||
f.Func.Nname = newfuncnamel(p.pos(fun.Name), name, f.Func)
|
f.Func().Nname = newfuncnamel(p.pos(fun.Name), name, f.Func())
|
||||||
f.Func.Nname.Name.Defn = f
|
f.Func().Nname.Name().Defn = f
|
||||||
f.Func.Nname.Name.Param.Ntype = t
|
f.Func().Nname.Name().Param.Ntype = t
|
||||||
|
|
||||||
if pragma, ok := fun.Pragma.(*Pragma); ok {
|
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 {
|
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
|
pragma.Flag &^= FuncPragmas
|
||||||
p.checkUnused(pragma)
|
p.checkUnused(pragma)
|
||||||
}
|
}
|
||||||
|
|
||||||
if fun.Recv == nil {
|
if fun.Recv == nil {
|
||||||
declare(f.Func.Nname, ir.PFUNC)
|
declare(f.Func().Nname, ir.PFUNC)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.funcBody(f, fun.Body)
|
p.funcBody(f, fun.Body)
|
||||||
|
|
||||||
if fun.Body != nil {
|
if fun.Body != nil {
|
||||||
if f.Func.Pragma&ir.Noescape != 0 {
|
if f.Func().Pragma&ir.Noescape != 0 {
|
||||||
base.ErrorfAt(f.Pos, "can only use //go:noescape with external func implementations")
|
base.ErrorfAt(f.Pos(), "can only use //go:noescape with external func implementations")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if base.Flag.Complete || strings.HasPrefix(ir.FuncName(f), "init.") {
|
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 {
|
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 {
|
func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *ir.Node {
|
||||||
n := p.nod(typ, ir.OTFUNC, nil, nil)
|
n := p.nod(typ, ir.OTFUNC, nil, nil)
|
||||||
if recv != 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.PtrList().Set(p.params(typ.ParamList, true))
|
||||||
n.Rlist.Set(p.params(typ.ResultList, false))
|
n.PtrRlist().Set(p.params(typ.ResultList, false))
|
||||||
return n
|
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)
|
n := p.nodSym(param, ir.ODCLFIELD, typ, name)
|
||||||
|
|
||||||
// rewrite ...T parameter
|
// rewrite ...T parameter
|
||||||
if typ.Op == ir.ODDD {
|
if typ.Op() == ir.ODDD {
|
||||||
if !dddOk {
|
if !dddOk {
|
||||||
// We mark these as syntax errors to get automatic elimination
|
// We mark these as syntax errors to get automatic elimination
|
||||||
// of multiple such errors per line (see ErrorfAt in subr.go).
|
// 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)
|
p.errorAt(param.Name.Pos(), "syntax error: cannot use ... with non-final parameter %s", param.Name.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typ.Op = ir.OTARRAY
|
typ.SetOp(ir.OTARRAY)
|
||||||
typ.Right = typ.Left
|
typ.SetRight(typ.Left())
|
||||||
typ.Left = nil
|
typ.SetLeft(nil)
|
||||||
n.SetIsDDD(true)
|
n.SetIsDDD(true)
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
n.Left.SetIsDDD(true)
|
n.Left().SetIsDDD(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -658,20 +658,20 @@ func (p *noder) expr(expr syntax.Expr) *ir.Node {
|
||||||
case *syntax.BasicLit:
|
case *syntax.BasicLit:
|
||||||
n := ir.NewLiteral(p.basicLit(expr))
|
n := ir.NewLiteral(p.basicLit(expr))
|
||||||
if expr.Kind == syntax.RuneLit {
|
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
|
n.SetDiag(expr.Bad) // avoid follow-on errors if there was a syntax error
|
||||||
return n
|
return n
|
||||||
case *syntax.CompositeLit:
|
case *syntax.CompositeLit:
|
||||||
n := p.nod(expr, ir.OCOMPLIT, nil, nil)
|
n := p.nod(expr, ir.OCOMPLIT, nil, nil)
|
||||||
if expr.Type != nil {
|
if expr.Type != nil {
|
||||||
n.Right = p.expr(expr.Type)
|
n.SetRight(p.expr(expr.Type))
|
||||||
}
|
}
|
||||||
l := p.exprs(expr.ElemList)
|
l := p.exprs(expr.ElemList)
|
||||||
for i, e := range l {
|
for i, e := range l {
|
||||||
l[i] = p.wrapname(expr.ElemList[i], e)
|
l[i] = p.wrapname(expr.ElemList[i], e)
|
||||||
}
|
}
|
||||||
n.List.Set(l)
|
n.PtrList().Set(l)
|
||||||
base.Pos = p.makeXPos(expr.Rbrace)
|
base.Pos = p.makeXPos(expr.Rbrace)
|
||||||
return n
|
return n
|
||||||
case *syntax.KeyValueExpr:
|
case *syntax.KeyValueExpr:
|
||||||
|
|
@ -684,12 +684,12 @@ func (p *noder) expr(expr syntax.Expr) *ir.Node {
|
||||||
case *syntax.SelectorExpr:
|
case *syntax.SelectorExpr:
|
||||||
// parser.new_dotname
|
// parser.new_dotname
|
||||||
obj := p.expr(expr.X)
|
obj := p.expr(expr.X)
|
||||||
if obj.Op == ir.OPACK {
|
if obj.Op() == ir.OPACK {
|
||||||
obj.Name.SetUsed(true)
|
obj.Name().SetUsed(true)
|
||||||
return importName(obj.Name.Pkg.Lookup(expr.Sel.Value))
|
return importName(obj.Name().Pkg.Lookup(expr.Sel.Value))
|
||||||
}
|
}
|
||||||
n := nodSym(ir.OXDOT, obj, p.name(expr.Sel))
|
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
|
return n
|
||||||
case *syntax.IndexExpr:
|
case *syntax.IndexExpr:
|
||||||
return p.nod(expr, ir.OINDEX, p.expr(expr.X), p.expr(expr.Index))
|
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))
|
return p.nod(expr, p.binOp(expr.Op), x, p.expr(expr.Y))
|
||||||
case *syntax.CallExpr:
|
case *syntax.CallExpr:
|
||||||
n := p.nod(expr, ir.OCALL, p.expr(expr.Fun), nil)
|
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)
|
n.SetIsDDD(expr.HasDots)
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
|
@ -752,9 +752,9 @@ func (p *noder) expr(expr syntax.Expr) *ir.Node {
|
||||||
case *syntax.TypeSwitchGuard:
|
case *syntax.TypeSwitchGuard:
|
||||||
n := p.nod(expr, ir.OTYPESW, nil, p.expr(expr.X))
|
n := p.nod(expr, ir.OTYPESW, nil, p.expr(expr.X))
|
||||||
if expr.Lhs != nil {
|
if expr.Lhs != nil {
|
||||||
n.Left = p.declName(expr.Lhs)
|
n.SetLeft(p.declName(expr.Lhs))
|
||||||
if ir.IsBlank(n.Left) {
|
if ir.IsBlank(n.Left()) {
|
||||||
base.Errorf("invalid variable name %v in type switch", n.Left)
|
base.Errorf("invalid variable name %v in type switch", n.Left())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
@ -804,7 +804,7 @@ func (p *noder) sum(x syntax.Expr) *ir.Node {
|
||||||
chunks := make([]string, 0, 1)
|
chunks := make([]string, 0, 1)
|
||||||
|
|
||||||
n := p.expr(x)
|
n := p.expr(x)
|
||||||
if ir.IsConst(n, constant.String) && n.Sym == nil {
|
if ir.IsConst(n, constant.String) && n.Sym() == nil {
|
||||||
nstr = n
|
nstr = n
|
||||||
chunks = append(chunks, nstr.StringVal())
|
chunks = append(chunks, nstr.StringVal())
|
||||||
}
|
}
|
||||||
|
|
@ -813,7 +813,7 @@ func (p *noder) sum(x syntax.Expr) *ir.Node {
|
||||||
add := adds[i]
|
add := adds[i]
|
||||||
|
|
||||||
r := p.expr(add.Y)
|
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 {
|
if nstr != nil {
|
||||||
// Collapse r into nstr instead of adding to n.
|
// Collapse r into nstr instead of adding to n.
|
||||||
chunks = append(chunks, r.StringVal())
|
chunks = append(chunks, r.StringVal())
|
||||||
|
|
@ -880,7 +880,7 @@ func (p *noder) structType(expr *syntax.StructType) *ir.Node {
|
||||||
|
|
||||||
p.setlineno(expr)
|
p.setlineno(expr)
|
||||||
n := p.nod(expr, ir.OTSTRUCT, nil, nil)
|
n := p.nod(expr, ir.OTSTRUCT, nil, nil)
|
||||||
n.List.Set(l)
|
n.PtrList().Set(l)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -894,7 +894,7 @@ func (p *noder) interfaceType(expr *syntax.InterfaceType) *ir.Node {
|
||||||
} else {
|
} else {
|
||||||
mname := p.name(method.Name)
|
mname := p.name(method.Name)
|
||||||
sig := p.typeExpr(method.Type)
|
sig := p.typeExpr(method.Type)
|
||||||
sig.Left = fakeRecv()
|
sig.SetLeft(fakeRecv())
|
||||||
n = p.nodSym(method, ir.ODCLFIELD, sig, mname)
|
n = p.nodSym(method, ir.ODCLFIELD, sig, mname)
|
||||||
ifacedcl(n)
|
ifacedcl(n)
|
||||||
}
|
}
|
||||||
|
|
@ -902,7 +902,7 @@ func (p *noder) interfaceType(expr *syntax.InterfaceType) *ir.Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
n := p.nod(expr, ir.OTINTER, nil, nil)
|
n := p.nod(expr, ir.OTINTER, nil, nil)
|
||||||
n.List.Set(l)
|
n.PtrList().Set(l)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -910,8 +910,8 @@ func (p *noder) packname(expr syntax.Expr) *types.Sym {
|
||||||
switch expr := expr.(type) {
|
switch expr := expr.(type) {
|
||||||
case *syntax.Name:
|
case *syntax.Name:
|
||||||
name := p.name(expr)
|
name := p.name(expr)
|
||||||
if n := oldname(name); n.Name != nil && n.Name.Pack != nil {
|
if n := oldname(name); n.Name() != nil && n.Name().Pack != nil {
|
||||||
n.Name.Pack.Name.SetUsed(true)
|
n.Name().Pack.Name().SetUsed(true)
|
||||||
}
|
}
|
||||||
return name
|
return name
|
||||||
case *syntax.SelectorExpr:
|
case *syntax.SelectorExpr:
|
||||||
|
|
@ -922,12 +922,12 @@ func (p *noder) packname(expr syntax.Expr) *types.Sym {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
var pkg *types.Pkg
|
var pkg *types.Pkg
|
||||||
if def.Op != ir.OPACK {
|
if def.Op() != ir.OPACK {
|
||||||
base.Errorf("%v is not a package", name)
|
base.Errorf("%v is not a package", name)
|
||||||
pkg = ir.LocalPkg
|
pkg = ir.LocalPkg
|
||||||
} else {
|
} else {
|
||||||
def.Name.SetUsed(true)
|
def.Name().SetUsed(true)
|
||||||
pkg = def.Name.Pkg
|
pkg = def.Name().Pkg
|
||||||
}
|
}
|
||||||
return pkg.Lookup(expr.Sel.Value)
|
return pkg.Lookup(expr.Sel.Value)
|
||||||
}
|
}
|
||||||
|
|
@ -948,7 +948,7 @@ func (p *noder) embedded(typ syntax.Expr) *ir.Node {
|
||||||
n.SetEmbedded(true)
|
n.SetEmbedded(true)
|
||||||
|
|
||||||
if isStar {
|
if isStar {
|
||||||
n.Left = p.nod(op, ir.ODEREF, n.Left, nil)
|
n.SetLeft(p.nod(op, ir.ODEREF, n.Left(), nil))
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -962,8 +962,8 @@ func (p *noder) stmtsFall(stmts []syntax.Stmt, fallOK bool) []*ir.Node {
|
||||||
for i, stmt := range stmts {
|
for i, stmt := range stmts {
|
||||||
s := p.stmtFall(stmt, fallOK && i+1 == len(stmts))
|
s := p.stmtFall(stmt, fallOK && i+1 == len(stmts))
|
||||||
if s == nil {
|
if s == nil {
|
||||||
} else if s.Op == ir.OBLOCK && s.Ninit.Len() == 0 {
|
} else if s.Op() == ir.OBLOCK && s.Init().Len() == 0 {
|
||||||
nodes = append(nodes, s.List.Slice()...)
|
nodes = append(nodes, s.List().Slice()...)
|
||||||
} else {
|
} else {
|
||||||
nodes = append(nodes, s)
|
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 {
|
if len(lhs) == 1 && len(rhs) == 1 {
|
||||||
// common case
|
// common case
|
||||||
n.Left = lhs[0]
|
n.SetLeft(lhs[0])
|
||||||
n.Right = rhs[0]
|
n.SetRight(rhs[0])
|
||||||
} else {
|
} else {
|
||||||
n.Op = ir.OAS2
|
n.SetOp(ir.OAS2)
|
||||||
n.List.Set(lhs)
|
n.PtrList().Set(lhs)
|
||||||
n.Rlist.Set(rhs)
|
n.PtrRlist().Set(rhs)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
|
@ -1038,7 +1038,7 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *ir.Node {
|
||||||
}
|
}
|
||||||
n := p.nod(stmt, op, nil, nil)
|
n := p.nod(stmt, op, nil, nil)
|
||||||
if stmt.Label != nil {
|
if stmt.Label != nil {
|
||||||
n.Sym = p.name(stmt.Label)
|
n.SetSym(p.name(stmt.Label))
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
case *syntax.CallStmt:
|
case *syntax.CallStmt:
|
||||||
|
|
@ -1058,17 +1058,17 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *ir.Node {
|
||||||
results = p.exprList(stmt.Results)
|
results = p.exprList(stmt.Results)
|
||||||
}
|
}
|
||||||
n := p.nod(stmt, ir.ORETURN, nil, nil)
|
n := p.nod(stmt, ir.ORETURN, nil, nil)
|
||||||
n.List.Set(results)
|
n.PtrList().Set(results)
|
||||||
if n.List.Len() == 0 && Curfn != nil {
|
if n.List().Len() == 0 && Curfn != nil {
|
||||||
for _, ln := range Curfn.Func.Dcl {
|
for _, ln := range Curfn.Func().Dcl {
|
||||||
if ln.Class() == ir.PPARAM {
|
if ln.Class() == ir.PPARAM {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if ln.Class() != ir.PPARAMOUT {
|
if ln.Class() != ir.PPARAMOUT {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if ir.AsNode(ln.Sym.Def) != ln {
|
if ir.AsNode(ln.Sym().Def) != ln {
|
||||||
base.Errorf("%s is shadowed during return", ln.Sym.Name)
|
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
|
newOrErr = true
|
||||||
n := NewName(sym)
|
n := NewName(sym)
|
||||||
declare(n, dclcontext)
|
declare(n, dclcontext)
|
||||||
n.Name.Defn = defn
|
n.Name().Defn = defn
|
||||||
defn.Ninit.Append(ir.Nod(ir.ODCL, n, nil))
|
defn.PtrInit().Append(ir.Nod(ir.ODCL, n, nil))
|
||||||
res[i] = n
|
res[i] = n
|
||||||
}
|
}
|
||||||
|
|
||||||
if !newOrErr {
|
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
|
return res
|
||||||
}
|
}
|
||||||
|
|
@ -1156,18 +1156,18 @@ func (p *noder) ifStmt(stmt *syntax.IfStmt) *ir.Node {
|
||||||
p.openScope(stmt.Pos())
|
p.openScope(stmt.Pos())
|
||||||
n := p.nod(stmt, ir.OIF, nil, nil)
|
n := p.nod(stmt, ir.OIF, nil, nil)
|
||||||
if stmt.Init != nil {
|
if stmt.Init != nil {
|
||||||
n.Ninit.Set1(p.stmt(stmt.Init))
|
n.PtrInit().Set1(p.stmt(stmt.Init))
|
||||||
}
|
}
|
||||||
if stmt.Cond != nil {
|
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 {
|
if stmt.Else != nil {
|
||||||
e := p.stmt(stmt.Else)
|
e := p.stmt(stmt.Else)
|
||||||
if e.Op == ir.OBLOCK && e.Ninit.Len() == 0 {
|
if e.Op() == ir.OBLOCK && e.Init().Len() == 0 {
|
||||||
n.Rlist.Set(e.List.Slice())
|
n.PtrRlist().Set(e.List().Slice())
|
||||||
} else {
|
} else {
|
||||||
n.Rlist.Set1(e)
|
n.PtrRlist().Set1(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.closeAnotherScope()
|
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))
|
n = p.nod(r, ir.ORANGE, nil, p.expr(r.X))
|
||||||
if r.Lhs != nil {
|
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 {
|
} else {
|
||||||
n = p.nod(stmt, ir.OFOR, nil, nil)
|
n = p.nod(stmt, ir.OFOR, nil, nil)
|
||||||
if stmt.Init != nil {
|
if stmt.Init != nil {
|
||||||
n.Ninit.Set1(p.stmt(stmt.Init))
|
n.PtrInit().Set1(p.stmt(stmt.Init))
|
||||||
}
|
}
|
||||||
if stmt.Cond != nil {
|
if stmt.Cond != nil {
|
||||||
n.Left = p.expr(stmt.Cond)
|
n.SetLeft(p.expr(stmt.Cond))
|
||||||
}
|
}
|
||||||
if stmt.Post != nil {
|
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()
|
p.closeAnotherScope()
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -1207,17 +1207,17 @@ func (p *noder) switchStmt(stmt *syntax.SwitchStmt) *ir.Node {
|
||||||
p.openScope(stmt.Pos())
|
p.openScope(stmt.Pos())
|
||||||
n := p.nod(stmt, ir.OSWITCH, nil, nil)
|
n := p.nod(stmt, ir.OSWITCH, nil, nil)
|
||||||
if stmt.Init != nil {
|
if stmt.Init != nil {
|
||||||
n.Ninit.Set1(p.stmt(stmt.Init))
|
n.PtrInit().Set1(p.stmt(stmt.Init))
|
||||||
}
|
}
|
||||||
if stmt.Tag != nil {
|
if stmt.Tag != nil {
|
||||||
n.Left = p.expr(stmt.Tag)
|
n.SetLeft(p.expr(stmt.Tag))
|
||||||
}
|
}
|
||||||
|
|
||||||
tswitch := n.Left
|
tswitch := n.Left()
|
||||||
if tswitch != nil && tswitch.Op != ir.OTYPESW {
|
if tswitch != nil && tswitch.Op() != ir.OTYPESW {
|
||||||
tswitch = nil
|
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)
|
p.closeScope(stmt.Rbrace)
|
||||||
return n
|
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)
|
n := p.nod(clause, ir.OCASE, nil, nil)
|
||||||
if clause.Cases != 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 {
|
if tswitch != nil && tswitch.Left() != nil {
|
||||||
nn := NewName(tswitch.Left.Sym)
|
nn := NewName(tswitch.Left().Sym())
|
||||||
declare(nn, dclcontext)
|
declare(nn, dclcontext)
|
||||||
n.Rlist.Set1(nn)
|
n.PtrRlist().Set1(nn)
|
||||||
// keep track of the instances for reporting unused
|
// keep track of the instances for reporting unused
|
||||||
nn.Name.Defn = tswitch
|
nn.Name().Defn = tswitch
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim trailing empty statements. We omit them from
|
// 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]
|
body = body[:len(body)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Nbody.Set(p.stmtsFall(body, true))
|
n.PtrBody().Set(p.stmtsFall(body, true))
|
||||||
if l := n.Nbody.Len(); l > 0 && n.Nbody.Index(l-1).Op == ir.OFALL {
|
if l := n.Body().Len(); l > 0 && n.Body().Index(l-1).Op() == ir.OFALL {
|
||||||
if tswitch != nil {
|
if tswitch != nil {
|
||||||
base.Errorf("cannot fallthrough in type switch")
|
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 {
|
func (p *noder) selectStmt(stmt *syntax.SelectStmt) *ir.Node {
|
||||||
n := p.nod(stmt, ir.OSELECT, nil, nil)
|
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
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1290,9 +1290,9 @@ func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*
|
||||||
|
|
||||||
n := p.nod(clause, ir.OCASE, nil, nil)
|
n := p.nod(clause, ir.OCASE, nil, nil)
|
||||||
if clause.Comm != 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)
|
nodes = append(nodes, n)
|
||||||
}
|
}
|
||||||
if len(clauses) > 0 {
|
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)
|
ls = p.stmtFall(label.Stmt, fallOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
lhs.Name.Defn = ls
|
lhs.Name().Defn = ls
|
||||||
l := []*ir.Node{lhs}
|
l := []*ir.Node{lhs}
|
||||||
if ls != nil {
|
if ls != nil {
|
||||||
if ls.Op == ir.OBLOCK && ls.Ninit.Len() == 0 {
|
if ls.Op() == ir.OBLOCK && ls.Init().Len() == 0 {
|
||||||
l = append(l, ls.List.Slice()...)
|
l = append(l, ls.List().Slice()...)
|
||||||
} else {
|
} else {
|
||||||
l = append(l, ls)
|
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 {
|
func (p *noder) wrapname(n syntax.Node, x *ir.Node) *ir.Node {
|
||||||
// These nodes do not carry line numbers.
|
// These nodes do not carry line numbers.
|
||||||
// Introduce a wrapper node to give them the correct line.
|
// Introduce a wrapper node to give them the correct line.
|
||||||
switch x.Op {
|
switch x.Op() {
|
||||||
case ir.OTYPE, ir.OLITERAL:
|
case ir.OTYPE, ir.OLITERAL:
|
||||||
if x.Sym == nil {
|
if x.Sym() == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
fallthrough
|
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 {
|
func (p *noder) nodSym(orig syntax.Node, op ir.Op, left *ir.Node, sym *types.Sym) *ir.Node {
|
||||||
n := nodSym(op, left, sym)
|
n := nodSym(op, left, sym)
|
||||||
n.Pos = p.pos(orig)
|
n.SetPos(p.pos(orig))
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1670,8 +1670,8 @@ func safeArg(name string) bool {
|
||||||
|
|
||||||
func mkname(sym *types.Sym) *ir.Node {
|
func mkname(sym *types.Sym) *ir.Node {
|
||||||
n := oldname(sym)
|
n := oldname(sym)
|
||||||
if n.Name != nil && n.Name.Pack != nil {
|
if n.Name() != nil && n.Name().Pack != nil {
|
||||||
n.Name.Pack.Name.SetUsed(true)
|
n.Name().Pack.Name().SetUsed(true)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ func dumpdata() {
|
||||||
for {
|
for {
|
||||||
for i := xtops; i < len(xtop); i++ {
|
for i := xtops; i < len(xtop); i++ {
|
||||||
n := xtop[i]
|
n := xtop[i]
|
||||||
if n.Op == ir.ODCLFUNC {
|
if n.Op() == ir.ODCLFUNC {
|
||||||
funccompile(n)
|
funccompile(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -204,12 +204,12 @@ func addptabs() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, exportn := range exportlist {
|
for _, exportn := range exportlist {
|
||||||
s := exportn.Sym
|
s := exportn.Sym()
|
||||||
n := ir.AsNode(s.Def)
|
n := ir.AsNode(s.Def)
|
||||||
if n == nil {
|
if n == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if n.Op != ir.ONAME {
|
if n.Op() != ir.ONAME {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !types.IsExported(s.Name) {
|
if !types.IsExported(s.Name) {
|
||||||
|
|
@ -218,37 +218,37 @@ func addptabs() {
|
||||||
if s.Pkg.Name != "main" {
|
if s.Pkg.Name != "main" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if n.Type.Etype == types.TFUNC && n.Class() == ir.PFUNC {
|
if n.Type().Etype == types.TFUNC && n.Class() == ir.PFUNC {
|
||||||
// function
|
// 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 {
|
} else {
|
||||||
// variable
|
// 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) {
|
func dumpGlobal(n *ir.Node) {
|
||||||
if n.Type == nil {
|
if n.Type() == nil {
|
||||||
base.Fatalf("external %v nil type\n", n)
|
base.Fatalf("external %v nil type\n", n)
|
||||||
}
|
}
|
||||||
if n.Class() == ir.PFUNC {
|
if n.Class() == ir.PFUNC {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Sym.Pkg != ir.LocalPkg {
|
if n.Sym().Pkg != ir.LocalPkg {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dowidth(n.Type)
|
dowidth(n.Type())
|
||||||
ggloblnod(n)
|
ggloblnod(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpGlobalConst(n *ir.Node) {
|
func dumpGlobalConst(n *ir.Node) {
|
||||||
// only export typed constants
|
// only export typed constants
|
||||||
t := n.Type
|
t := n.Type()
|
||||||
if t == nil {
|
if t == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Sym.Pkg != ir.LocalPkg {
|
if n.Sym().Pkg != ir.LocalPkg {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// only export integer constants for now
|
// only export integer constants for now
|
||||||
|
|
@ -263,13 +263,13 @@ func dumpGlobalConst(n *ir.Node) {
|
||||||
return
|
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() {
|
func dumpglobls() {
|
||||||
// add globals
|
// add globals
|
||||||
for _, n := range externdcl {
|
for _, n := range externdcl {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.ONAME:
|
case ir.ONAME:
|
||||||
dumpGlobal(n)
|
dumpGlobal(n)
|
||||||
case ir.OLITERAL:
|
case ir.OLITERAL:
|
||||||
|
|
@ -414,7 +414,7 @@ func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj.
|
||||||
if readonly {
|
if readonly {
|
||||||
sym = stringsym(pos, string(data))
|
sym = stringsym(pos, string(data))
|
||||||
} else {
|
} else {
|
||||||
sym = slicedata(pos, string(data)).Sym.Linksym()
|
sym = slicedata(pos, string(data)).Sym().Linksym()
|
||||||
}
|
}
|
||||||
if len(hash) > 0 {
|
if len(hash) > 0 {
|
||||||
sum := sha256.Sum256(data)
|
sum := sha256.Sum256(data)
|
||||||
|
|
@ -462,7 +462,7 @@ func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj.
|
||||||
} else {
|
} else {
|
||||||
// Emit a zero-length data symbol
|
// Emit a zero-length data symbol
|
||||||
// and then fix up length and content to use file.
|
// and then fix up length and content to use file.
|
||||||
symdata = slicedata(pos, "").Sym.Linksym()
|
symdata = slicedata(pos, "").Sym().Linksym()
|
||||||
symdata.Size = size
|
symdata.Size = size
|
||||||
symdata.Type = objabi.SNOPTRDATA
|
symdata.Type = objabi.SNOPTRDATA
|
||||||
info := symdata.NewFileInfo()
|
info := symdata.NewFileInfo()
|
||||||
|
|
@ -490,10 +490,10 @@ func slicedata(pos src.XPos, s string) *ir.Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
func slicebytes(nam *ir.Node, s string) {
|
func slicebytes(nam *ir.Node, s string) {
|
||||||
if nam.Op != ir.ONAME {
|
if nam.Op() != ir.ONAME {
|
||||||
base.Fatalf("slicebytes %v", nam)
|
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 {
|
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.
|
// slicesym writes a static slice symbol {&arr, lencap, lencap} to n.
|
||||||
// arr must be an ONAME. slicesym does not modify n.
|
// arr must be an ONAME. slicesym does not modify n.
|
||||||
func slicesym(n, arr *ir.Node, lencap int64) {
|
func slicesym(n, arr *ir.Node, lencap int64) {
|
||||||
s := n.Sym.Linksym()
|
s := n.Sym().Linksym()
|
||||||
off := n.Xoffset
|
off := n.Offset()
|
||||||
if arr.Op != ir.ONAME {
|
if arr.Op() != ir.ONAME {
|
||||||
base.Fatalf("slicesym non-name arr %v", arr)
|
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+sliceLenOffset, Widthptr, lencap)
|
||||||
s.WriteInt(base.Ctxt, off+sliceCapOffset, 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.
|
// addrsym writes the static address of a to n. a must be an ONAME.
|
||||||
// Neither n nor a is modified.
|
// Neither n nor a is modified.
|
||||||
func addrsym(n, a *ir.Node) {
|
func addrsym(n, a *ir.Node) {
|
||||||
if n.Op != ir.ONAME {
|
if n.Op() != ir.ONAME {
|
||||||
base.Fatalf("addrsym n op %v", n.Op)
|
base.Fatalf("addrsym n op %v", n.Op())
|
||||||
}
|
}
|
||||||
if n.Sym == nil {
|
if n.Sym() == nil {
|
||||||
base.Fatalf("addrsym nil n sym")
|
base.Fatalf("addrsym nil n sym")
|
||||||
}
|
}
|
||||||
if a.Op != ir.ONAME {
|
if a.Op() != ir.ONAME {
|
||||||
base.Fatalf("addrsym a op %v", a.Op)
|
base.Fatalf("addrsym a op %v", a.Op())
|
||||||
}
|
}
|
||||||
s := n.Sym.Linksym()
|
s := n.Sym().Linksym()
|
||||||
s.WriteAddr(base.Ctxt, n.Xoffset, Widthptr, a.Sym.Linksym(), a.Xoffset)
|
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.
|
// pfuncsym writes the static address of f to n. f must be a global function.
|
||||||
// Neither n nor f is modified.
|
// Neither n nor f is modified.
|
||||||
func pfuncsym(n, f *ir.Node) {
|
func pfuncsym(n, f *ir.Node) {
|
||||||
if n.Op != ir.ONAME {
|
if n.Op() != ir.ONAME {
|
||||||
base.Fatalf("pfuncsym n op %v", n.Op)
|
base.Fatalf("pfuncsym n op %v", n.Op())
|
||||||
}
|
}
|
||||||
if n.Sym == nil {
|
if n.Sym() == nil {
|
||||||
base.Fatalf("pfuncsym nil n sym")
|
base.Fatalf("pfuncsym nil n sym")
|
||||||
}
|
}
|
||||||
if f.Class() != ir.PFUNC {
|
if f.Class() != ir.PFUNC {
|
||||||
base.Fatalf("pfuncsym class not PFUNC %d", f.Class())
|
base.Fatalf("pfuncsym class not PFUNC %d", f.Class())
|
||||||
}
|
}
|
||||||
s := n.Sym.Linksym()
|
s := n.Sym().Linksym()
|
||||||
s.WriteAddr(base.Ctxt, n.Xoffset, Widthptr, funcsym(f.Sym).Linksym(), f.Xoffset)
|
s.WriteAddr(base.Ctxt, n.Offset(), Widthptr, funcsym(f.Sym()).Linksym(), f.Offset())
|
||||||
}
|
}
|
||||||
|
|
||||||
// litsym writes the static literal c to n.
|
// litsym writes the static literal c to n.
|
||||||
// Neither n nor c is modified.
|
// Neither n nor c is modified.
|
||||||
func litsym(n, c *ir.Node, wid int) {
|
func litsym(n, c *ir.Node, wid int) {
|
||||||
if n.Op != ir.ONAME {
|
if n.Op() != ir.ONAME {
|
||||||
base.Fatalf("litsym n op %v", n.Op)
|
base.Fatalf("litsym n op %v", n.Op())
|
||||||
}
|
}
|
||||||
if n.Sym == nil {
|
if n.Sym() == nil {
|
||||||
base.Fatalf("litsym nil n sym")
|
base.Fatalf("litsym nil n sym")
|
||||||
}
|
}
|
||||||
if !types.Identical(n.Type, 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)
|
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
|
return
|
||||||
}
|
}
|
||||||
if c.Op != ir.OLITERAL {
|
if c.Op() != ir.OLITERAL {
|
||||||
base.Fatalf("litsym c op %v", c.Op)
|
base.Fatalf("litsym c op %v", c.Op())
|
||||||
}
|
}
|
||||||
s := n.Sym.Linksym()
|
s := n.Sym().Linksym()
|
||||||
switch u := c.Val(); u.Kind() {
|
switch u := c.Val(); u.Kind() {
|
||||||
case constant.Bool:
|
case constant.Bool:
|
||||||
i := int64(obj.Bool2int(constant.BoolVal(u)))
|
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:
|
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:
|
case constant.Float:
|
||||||
f, _ := constant.Float64Val(u)
|
f, _ := constant.Float64Val(u)
|
||||||
switch n.Type.Etype {
|
switch n.Type().Etype {
|
||||||
case types.TFLOAT32:
|
case types.TFLOAT32:
|
||||||
s.WriteFloat32(base.Ctxt, n.Xoffset, float32(f))
|
s.WriteFloat32(base.Ctxt, n.Offset(), float32(f))
|
||||||
case types.TFLOAT64:
|
case types.TFLOAT64:
|
||||||
s.WriteFloat64(base.Ctxt, n.Xoffset, f)
|
s.WriteFloat64(base.Ctxt, n.Offset(), f)
|
||||||
}
|
}
|
||||||
|
|
||||||
case constant.Complex:
|
case constant.Complex:
|
||||||
re, _ := constant.Float64Val(constant.Real(u))
|
re, _ := constant.Float64Val(constant.Real(u))
|
||||||
im, _ := constant.Float64Val(constant.Imag(u))
|
im, _ := constant.Float64Val(constant.Imag(u))
|
||||||
switch n.Type.Etype {
|
switch n.Type().Etype {
|
||||||
case types.TCOMPLEX64:
|
case types.TCOMPLEX64:
|
||||||
s.WriteFloat32(base.Ctxt, n.Xoffset, float32(re))
|
s.WriteFloat32(base.Ctxt, n.Offset(), float32(re))
|
||||||
s.WriteFloat32(base.Ctxt, n.Xoffset+4, float32(im))
|
s.WriteFloat32(base.Ctxt, n.Offset()+4, float32(im))
|
||||||
case types.TCOMPLEX128:
|
case types.TCOMPLEX128:
|
||||||
s.WriteFloat64(base.Ctxt, n.Xoffset, re)
|
s.WriteFloat64(base.Ctxt, n.Offset(), re)
|
||||||
s.WriteFloat64(base.Ctxt, n.Xoffset+8, im)
|
s.WriteFloat64(base.Ctxt, n.Offset()+8, im)
|
||||||
}
|
}
|
||||||
|
|
||||||
case constant.String:
|
case constant.String:
|
||||||
i := constant.StringVal(u)
|
i := constant.StringVal(u)
|
||||||
symdata := stringsym(n.Pos, i)
|
symdata := stringsym(n.Pos(), i)
|
||||||
s.WriteAddr(base.Ctxt, n.Xoffset, Widthptr, symdata, 0)
|
s.WriteAddr(base.Ctxt, n.Offset(), Widthptr, symdata, 0)
|
||||||
s.WriteInt(base.Ctxt, n.Xoffset+int64(Widthptr), Widthptr, int64(len(i)))
|
s.WriteInt(base.Ctxt, n.Offset()+int64(Widthptr), Widthptr, int64(len(i)))
|
||||||
|
|
||||||
default:
|
default:
|
||||||
base.Fatalf("litsym unhandled OLITERAL %v", c)
|
base.Fatalf("litsym unhandled OLITERAL %v", c)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -28,30 +28,30 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func emitptrargsmap(fn *ir.Node) {
|
func emitptrargsmap(fn *ir.Node) {
|
||||||
if ir.FuncName(fn) == "_" || fn.Func.Nname.Sym.Linkname != "" {
|
if ir.FuncName(fn) == "_" || fn.Func().Nname.Sym().Linkname != "" {
|
||||||
return
|
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)
|
bv := bvalloc(int32(nptr) * 2)
|
||||||
nbitmap := 1
|
nbitmap := 1
|
||||||
if fn.Type.NumResults() > 0 {
|
if fn.Type().NumResults() > 0 {
|
||||||
nbitmap = 2
|
nbitmap = 2
|
||||||
}
|
}
|
||||||
off := duint32(lsym, 0, uint32(nbitmap))
|
off := duint32(lsym, 0, uint32(nbitmap))
|
||||||
off = duint32(lsym, off, uint32(bv.n))
|
off = duint32(lsym, off, uint32(bv.n))
|
||||||
|
|
||||||
if ir.IsMethod(fn) {
|
if ir.IsMethod(fn) {
|
||||||
onebitwalktype1(fn.Type.Recvs(), 0, bv)
|
onebitwalktype1(fn.Type().Recvs(), 0, bv)
|
||||||
}
|
}
|
||||||
if fn.Type.NumParams() > 0 {
|
if fn.Type().NumParams() > 0 {
|
||||||
onebitwalktype1(fn.Type.Params(), 0, bv)
|
onebitwalktype1(fn.Type().Params(), 0, bv)
|
||||||
}
|
}
|
||||||
off = dbvec(lsym, off, bv)
|
off = dbvec(lsym, off, bv)
|
||||||
|
|
||||||
if fn.Type.NumResults() > 0 {
|
if fn.Type().NumResults() > 0 {
|
||||||
onebitwalktype1(fn.Type.Results(), 0, bv)
|
onebitwalktype1(fn.Type().Results(), 0, bv)
|
||||||
off = dbvec(lsym, off, bv)
|
off = dbvec(lsym, off, bv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,30 +74,30 @@ func cmpstackvarlt(a, b *ir.Node) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.Class() != ir.PAUTO {
|
if a.Class() != ir.PAUTO {
|
||||||
return a.Xoffset < b.Xoffset
|
return a.Offset() < b.Offset()
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.Name.Used() != b.Name.Used() {
|
if a.Name().Used() != b.Name().Used() {
|
||||||
return a.Name.Used()
|
return a.Name().Used()
|
||||||
}
|
}
|
||||||
|
|
||||||
ap := a.Type.HasPointers()
|
ap := a.Type().HasPointers()
|
||||||
bp := b.Type.HasPointers()
|
bp := b.Type().HasPointers()
|
||||||
if ap != bp {
|
if ap != bp {
|
||||||
return ap
|
return ap
|
||||||
}
|
}
|
||||||
|
|
||||||
ap = a.Name.Needzero()
|
ap = a.Name().Needzero()
|
||||||
bp = b.Name.Needzero()
|
bp = b.Name().Needzero()
|
||||||
if ap != bp {
|
if ap != bp {
|
||||||
return ap
|
return ap
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.Type.Width != b.Type.Width {
|
if a.Type().Width != b.Type().Width {
|
||||||
return 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.
|
// 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) {
|
func (s *ssafn) AllocFrame(f *ssa.Func) {
|
||||||
s.stksize = 0
|
s.stksize = 0
|
||||||
s.stkptrsize = 0
|
s.stkptrsize = 0
|
||||||
fn := s.curfn.Func
|
fn := s.curfn.Func()
|
||||||
|
|
||||||
// Mark the PAUTO's unused.
|
// Mark the PAUTO's unused.
|
||||||
for _, ln := range fn.Dcl {
|
for _, ln := range fn.Dcl {
|
||||||
if ln.Class() == ir.PAUTO {
|
if ln.Class() == ir.PAUTO {
|
||||||
ln.Name.SetUsed(false)
|
ln.Name().SetUsed(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, l := range f.RegAlloc {
|
for _, l := range f.RegAlloc {
|
||||||
if ls, ok := l.(ssa.LocalSlot); ok {
|
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:
|
case ir.PPARAM, ir.PPARAMOUT:
|
||||||
// Don't modify nodfp; it is a global.
|
// Don't modify nodfp; it is a global.
|
||||||
if n != nodfp {
|
if n != nodfp {
|
||||||
n.Name.SetUsed(true)
|
n.Name().SetUsed(true)
|
||||||
}
|
}
|
||||||
case ir.PAUTO:
|
case ir.PAUTO:
|
||||||
n.Name.SetUsed(true)
|
n.Name().SetUsed(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !scratchUsed {
|
if !scratchUsed {
|
||||||
|
|
@ -155,16 +155,16 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
|
||||||
// Reassign stack offsets of the locals that are used.
|
// Reassign stack offsets of the locals that are used.
|
||||||
lastHasPtr := false
|
lastHasPtr := false
|
||||||
for i, n := range fn.Dcl {
|
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
|
continue
|
||||||
}
|
}
|
||||||
if !n.Name.Used() {
|
if !n.Name().Used() {
|
||||||
fn.Dcl = fn.Dcl[:i]
|
fn.Dcl = fn.Dcl[:i]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
dowidth(n.Type)
|
dowidth(n.Type())
|
||||||
w := n.Type.Width
|
w := n.Type().Width
|
||||||
if w >= thearch.MAXWIDTH || w < 0 {
|
if w >= thearch.MAXWIDTH || w < 0 {
|
||||||
base.Fatalf("bad width")
|
base.Fatalf("bad width")
|
||||||
}
|
}
|
||||||
|
|
@ -176,8 +176,8 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
|
||||||
w = 1
|
w = 1
|
||||||
}
|
}
|
||||||
s.stksize += w
|
s.stksize += w
|
||||||
s.stksize = Rnd(s.stksize, int64(n.Type.Align))
|
s.stksize = Rnd(s.stksize, int64(n.Type().Align))
|
||||||
if n.Type.HasPointers() {
|
if n.Type().HasPointers() {
|
||||||
s.stkptrsize = s.stksize
|
s.stkptrsize = s.stksize
|
||||||
lastHasPtr = true
|
lastHasPtr = true
|
||||||
} else {
|
} 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) {
|
if thearch.LinkArch.InFamily(sys.MIPS, sys.MIPS64, sys.ARM, sys.ARM64, sys.PPC64, sys.S390X) {
|
||||||
s.stksize = Rnd(s.stksize, int64(Widthptr))
|
s.stksize = Rnd(s.stksize, int64(Widthptr))
|
||||||
}
|
}
|
||||||
n.Xoffset = -s.stksize
|
n.SetOffset(-s.stksize)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.stksize = Rnd(s.stksize, int64(Widthreg))
|
s.stksize = Rnd(s.stksize, int64(Widthreg))
|
||||||
|
|
@ -195,10 +195,10 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
|
||||||
|
|
||||||
func funccompile(fn *ir.Node) {
|
func funccompile(fn *ir.Node) {
|
||||||
if Curfn != nil {
|
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 {
|
if base.Errors() == 0 {
|
||||||
base.Fatalf("funccompile missing type")
|
base.Fatalf("funccompile missing type")
|
||||||
}
|
}
|
||||||
|
|
@ -206,11 +206,11 @@ func funccompile(fn *ir.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign parameter offsets
|
// assign parameter offsets
|
||||||
dowidth(fn.Type)
|
dowidth(fn.Type())
|
||||||
|
|
||||||
if fn.Nbody.Len() == 0 {
|
if fn.Body().Len() == 0 {
|
||||||
// Initialize ABI wrappers if necessary.
|
// Initialize ABI wrappers if necessary.
|
||||||
initLSym(fn.Func, false)
|
initLSym(fn.Func(), false)
|
||||||
emitptrargsmap(fn)
|
emitptrargsmap(fn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -234,7 +234,7 @@ func compile(fn *ir.Node) {
|
||||||
// Set up the function's LSym early to avoid data races with the assemblers.
|
// 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
|
// Do this before walk, as walk needs the LSym to set attributes/relocations
|
||||||
// (e.g. in markTypeUsedInInterface).
|
// (e.g. in markTypeUsedInInterface).
|
||||||
initLSym(fn.Func, true)
|
initLSym(fn.Func(), true)
|
||||||
|
|
||||||
walk(fn)
|
walk(fn)
|
||||||
if base.Errors() > errorsBefore {
|
if base.Errors() > errorsBefore {
|
||||||
|
|
@ -259,15 +259,15 @@ func compile(fn *ir.Node) {
|
||||||
// be types of stack objects. We need to do this here
|
// be types of stack objects. We need to do this here
|
||||||
// because symbols must be allocated before the parallel
|
// because symbols must be allocated before the parallel
|
||||||
// phase of the compiler.
|
// phase of the compiler.
|
||||||
for _, n := range fn.Func.Dcl {
|
for _, n := range fn.Func().Dcl {
|
||||||
switch n.Class() {
|
switch n.Class() {
|
||||||
case ir.PPARAM, ir.PPARAMOUT, ir.PAUTO:
|
case ir.PPARAM, ir.PPARAMOUT, ir.PAUTO:
|
||||||
if livenessShouldTrack(n) && n.Name.Addrtaken() {
|
if livenessShouldTrack(n) && n.Name().Addrtaken() {
|
||||||
dtypesym(n.Type)
|
dtypesym(n.Type())
|
||||||
// Also make sure we allocate a linker symbol
|
// Also make sure we allocate a linker symbol
|
||||||
// for the stack object data, for the same reason.
|
// for the stack object data, for the same reason.
|
||||||
if fn.Func.LSym.Func().StackObjects == nil {
|
if fn.Func().LSym.Func().StackObjects == nil {
|
||||||
fn.Func.LSym.Func().StackObjects = base.Ctxt.Lookup(fn.Func.LSym.Name + ".stkobj")
|
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
|
// inline candidate but then never inlined (presumably because we
|
||||||
// found no call sites).
|
// found no call sites).
|
||||||
func isInlinableButNotInlined(fn *ir.Node) bool {
|
func isInlinableButNotInlined(fn *ir.Node) bool {
|
||||||
if fn.Func.Nname.Func.Inl == nil {
|
if fn.Func().Nname.Func().Inl == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if fn.Sym == nil {
|
if fn.Sym() == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return !fn.Sym.Linksym().WasInlined()
|
return !fn.Sym().Linksym().WasInlined()
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxStackSize = 1 << 30
|
const maxStackSize = 1 << 30
|
||||||
|
|
@ -318,9 +318,9 @@ const maxStackSize = 1 << 30
|
||||||
func compileSSA(fn *ir.Node, worker int) {
|
func compileSSA(fn *ir.Node, worker int) {
|
||||||
f := buildssa(fn, worker)
|
f := buildssa(fn, worker)
|
||||||
// Note: check arg size to fix issue 25507.
|
// 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()
|
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()
|
largeStackFramesMu.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -336,14 +336,14 @@ func compileSSA(fn *ir.Node, worker int) {
|
||||||
if pp.Text.To.Offset >= maxStackSize {
|
if pp.Text.To.Offset >= maxStackSize {
|
||||||
largeStackFramesMu.Lock()
|
largeStackFramesMu.Lock()
|
||||||
locals := f.Frontend().(*ssafn).stksize
|
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()
|
largeStackFramesMu.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pp.Flush() // assemble, fill in boilerplate, etc.
|
pp.Flush() // assemble, fill in boilerplate, etc.
|
||||||
// fieldtrack must be called after pp.Flush. See issue 20014.
|
// 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() {
|
func init() {
|
||||||
|
|
@ -371,7 +371,7 @@ func compileFunctions() {
|
||||||
// since they're most likely to be the slowest.
|
// since they're most likely to be the slowest.
|
||||||
// This helps avoid stragglers.
|
// This helps avoid stragglers.
|
||||||
sort.Slice(compilequeue, func(i, j int) bool {
|
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
|
var wg sync.WaitGroup
|
||||||
|
|
@ -399,8 +399,8 @@ func compileFunctions() {
|
||||||
|
|
||||||
func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.Scope, dwarf.InlCalls) {
|
func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.Scope, dwarf.InlCalls) {
|
||||||
fn := curfn.(*ir.Node)
|
fn := curfn.(*ir.Node)
|
||||||
if fn.Func.Nname != nil {
|
if fn.Func().Nname != nil {
|
||||||
if expect := fn.Func.Nname.Sym.Linksym(); fnsym != expect {
|
if expect := fn.Func().Nname.Sym().Linksym(); fnsym != expect {
|
||||||
base.Fatalf("unexpected fnsym: %v != %v", 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.
|
// These two adjustments keep toolstash -cmp working for now.
|
||||||
// Deciding the right answer is, as they say, future work.
|
// Deciding the right answer is, as they say, future work.
|
||||||
isODCLFUNC := fn.Op == ir.ODCLFUNC
|
isODCLFUNC := fn.Op() == ir.ODCLFUNC
|
||||||
|
|
||||||
var apdecls []*ir.Node
|
var apdecls []*ir.Node
|
||||||
// Populate decls for fn.
|
// Populate decls for fn.
|
||||||
if isODCLFUNC {
|
if isODCLFUNC {
|
||||||
for _, n := range fn.Func.Dcl {
|
for _, n := range fn.Func().Dcl {
|
||||||
if n.Op != ir.ONAME { // might be OTYPE or OLITERAL
|
if n.Op() != ir.ONAME { // might be OTYPE or OLITERAL
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
switch n.Class() {
|
switch n.Class() {
|
||||||
case ir.PAUTO:
|
case ir.PAUTO:
|
||||||
if !n.Name.Used() {
|
if !n.Name().Used() {
|
||||||
// Text == nil -> generating abstract function
|
// Text == nil -> generating abstract function
|
||||||
if fnsym.Func().Text != nil {
|
if fnsym.Func().Text != nil {
|
||||||
base.Fatalf("debuginfo unused node (AllocFrame should truncate fn.Func.Dcl)")
|
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
|
// For each type referenced by the functions auto vars but not
|
||||||
// already referenced by a dwarf var, attach an R_USETYPE relocation to
|
// 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
|
var varScopes []ir.ScopeID
|
||||||
for _, decl := range decls {
|
for _, decl := range decls {
|
||||||
pos := declPos(decl)
|
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)
|
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 {
|
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:
|
// It's not clear which position is correct for captured variables here:
|
||||||
// * decl.Pos is the wrong position for captured variables, in the inner
|
// * decl.Pos is the wrong position for captured variables, in the inner
|
||||||
// function, but it is the right position in the outer function.
|
// function, but it is the right position in the outer function.
|
||||||
|
|
@ -505,9 +505,9 @@ func declPos(decl *ir.Node) src.XPos {
|
||||||
// case statement.
|
// case statement.
|
||||||
// This code is probably wrong for type switch variables that are also
|
// This code is probably wrong for type switch variables that are also
|
||||||
// captured.
|
// 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
|
// 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 {
|
func createSimpleVar(fnsym *obj.LSym, n *ir.Node) *dwarf.Var {
|
||||||
var abbrev int
|
var abbrev int
|
||||||
offs := n.Xoffset
|
offs := n.Offset()
|
||||||
|
|
||||||
switch n.Class() {
|
switch n.Class() {
|
||||||
case ir.PAUTO:
|
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)
|
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())
|
delete(fnsym.Func().Autot, ngotype(n).Linksym())
|
||||||
inlIndex := 0
|
inlIndex := 0
|
||||||
if base.Flag.GenDwarfInl > 1 {
|
if base.Flag.GenDwarfInl > 1 {
|
||||||
if n.Name.InlFormal() || n.Name.InlLocal() {
|
if n.Name().InlFormal() || n.Name().InlLocal() {
|
||||||
inlIndex = posInlIndex(n.Pos) + 1
|
inlIndex = posInlIndex(n.Pos()) + 1
|
||||||
if n.Name.InlFormal() {
|
if n.Name().InlFormal() {
|
||||||
abbrev = dwarf.DW_ABRV_PARAM
|
abbrev = dwarf.DW_ABRV_PARAM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declpos := base.Ctxt.InnermostPos(declPos(n))
|
declpos := base.Ctxt.InnermostPos(declPos(n))
|
||||||
return &dwarf.Var{
|
return &dwarf.Var{
|
||||||
Name: n.Sym.Name,
|
Name: n.Sym().Name,
|
||||||
IsReturnValue: n.Class() == ir.PPARAMOUT,
|
IsReturnValue: n.Class() == ir.PPARAMOUT,
|
||||||
IsInlFormal: n.Name.InlFormal(),
|
IsInlFormal: n.Name().InlFormal(),
|
||||||
Abbrev: abbrev,
|
Abbrev: abbrev,
|
||||||
StackOffset: int32(offs),
|
StackOffset: int32(offs),
|
||||||
Type: base.Ctxt.Lookup(typename),
|
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 {
|
if _, found := selected[n]; found {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
c := n.Sym.Name[0]
|
c := n.Sym().Name[0]
|
||||||
if c == '.' || n.Type.IsUntyped() {
|
if c == '.' || n.Type().IsUntyped() {
|
||||||
continue
|
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
|
// SSA-able args get location lists, and may move in and
|
||||||
// out of registers, so those are handled elsewhere.
|
// out of registers, so those are handled elsewhere.
|
||||||
// Autos and named output params seem to get handled
|
// 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)
|
decls = append(decls, n)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
typename := dwarf.InfoPrefix + typesymname(n.Type)
|
typename := dwarf.InfoPrefix + typesymname(n.Type())
|
||||||
decls = append(decls, n)
|
decls = append(decls, n)
|
||||||
abbrev := dwarf.DW_ABRV_AUTO_LOCLIST
|
abbrev := dwarf.DW_ABRV_AUTO_LOCLIST
|
||||||
isReturnValue := (n.Class() == ir.PPARAMOUT)
|
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
|
// misleading location for the param (we want pointer-to-heap
|
||||||
// and not stack).
|
// and not stack).
|
||||||
// TODO(thanm): generate a better location expression
|
// 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) {
|
if stackcopy != nil && (stackcopy.Class() == ir.PPARAM || stackcopy.Class() == ir.PPARAMOUT) {
|
||||||
abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
|
abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
|
||||||
isReturnValue = (stackcopy.Class() == ir.PPARAMOUT)
|
isReturnValue = (stackcopy.Class() == ir.PPARAMOUT)
|
||||||
|
|
@ -675,19 +675,19 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir
|
||||||
}
|
}
|
||||||
inlIndex := 0
|
inlIndex := 0
|
||||||
if base.Flag.GenDwarfInl > 1 {
|
if base.Flag.GenDwarfInl > 1 {
|
||||||
if n.Name.InlFormal() || n.Name.InlLocal() {
|
if n.Name().InlFormal() || n.Name().InlLocal() {
|
||||||
inlIndex = posInlIndex(n.Pos) + 1
|
inlIndex = posInlIndex(n.Pos()) + 1
|
||||||
if n.Name.InlFormal() {
|
if n.Name().InlFormal() {
|
||||||
abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
|
abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declpos := base.Ctxt.InnermostPos(n.Pos)
|
declpos := base.Ctxt.InnermostPos(n.Pos())
|
||||||
vars = append(vars, &dwarf.Var{
|
vars = append(vars, &dwarf.Var{
|
||||||
Name: n.Sym.Name,
|
Name: n.Sym().Name,
|
||||||
IsReturnValue: isReturnValue,
|
IsReturnValue: isReturnValue,
|
||||||
Abbrev: abbrev,
|
Abbrev: abbrev,
|
||||||
StackOffset: int32(n.Xoffset),
|
StackOffset: int32(n.Offset()),
|
||||||
Type: base.Ctxt.Lookup(typename),
|
Type: base.Ctxt.Lookup(typename),
|
||||||
DeclFile: declpos.RelFilename(),
|
DeclFile: declpos.RelFilename(),
|
||||||
DeclLine: declpos.RelLine(),
|
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 {
|
func preInliningDcls(fnsym *obj.LSym) []*ir.Node {
|
||||||
fn := base.Ctxt.DwFixups.GetPrecursorFunc(fnsym).(*ir.Node)
|
fn := base.Ctxt.DwFixups.GetPrecursorFunc(fnsym).(*ir.Node)
|
||||||
var rdcl []*ir.Node
|
var rdcl []*ir.Node
|
||||||
for _, n := range fn.Func.Inl.Dcl {
|
for _, n := range fn.Func().Inl.Dcl {
|
||||||
c := n.Sym.Name[0]
|
c := n.Sym().Name[0]
|
||||||
// Avoid reporting "_" parameters, since if there are more than
|
// Avoid reporting "_" parameters, since if there are more than
|
||||||
// one, it can result in a collision later on, as in #23179.
|
// 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
|
continue
|
||||||
}
|
}
|
||||||
rdcl = append(rdcl, n)
|
rdcl = append(rdcl, n)
|
||||||
|
|
@ -741,7 +741,7 @@ func stackOffset(slot ssa.LocalSlot) int32 {
|
||||||
case ir.PPARAM, ir.PPARAMOUT:
|
case ir.PPARAM, ir.PPARAMOUT:
|
||||||
off += base.Ctxt.FixedFrameSize()
|
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.
|
// 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."):]
|
typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
|
||||||
inlIndex := 0
|
inlIndex := 0
|
||||||
if base.Flag.GenDwarfInl > 1 {
|
if base.Flag.GenDwarfInl > 1 {
|
||||||
if n.Name.InlFormal() || n.Name.InlLocal() {
|
if n.Name().InlFormal() || n.Name().InlLocal() {
|
||||||
inlIndex = posInlIndex(n.Pos) + 1
|
inlIndex = posInlIndex(n.Pos()) + 1
|
||||||
if n.Name.InlFormal() {
|
if n.Name().InlFormal() {
|
||||||
abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
|
abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declpos := base.Ctxt.InnermostPos(n.Pos)
|
declpos := base.Ctxt.InnermostPos(n.Pos())
|
||||||
dvar := &dwarf.Var{
|
dvar := &dwarf.Var{
|
||||||
Name: n.Sym.Name,
|
Name: n.Sym().Name,
|
||||||
IsReturnValue: n.Class() == ir.PPARAMOUT,
|
IsReturnValue: n.Class() == ir.PPARAMOUT,
|
||||||
IsInlFormal: n.Name.InlFormal(),
|
IsInlFormal: n.Name().InlFormal(),
|
||||||
Abbrev: abbrev,
|
Abbrev: abbrev,
|
||||||
Type: base.Ctxt.Lookup(typename),
|
Type: base.Ctxt.Lookup(typename),
|
||||||
// The stack offset is used as a sorting key, so for decomposed
|
// The stack offset is used as a sorting key, so for decomposed
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,12 @@ func typeWithPointers() *types.Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
func markUsed(n *ir.Node) *ir.Node {
|
func markUsed(n *ir.Node) *ir.Node {
|
||||||
n.Name.SetUsed(true)
|
n.Name().SetUsed(true)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func markNeedZero(n *ir.Node) *ir.Node {
|
func markNeedZero(n *ir.Node) *ir.Node {
|
||||||
n.Name.SetNeedzero(true)
|
n.Name().SetNeedzero(true)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,8 +43,8 @@ func TestCmpstackvar(t *testing.T) {
|
||||||
s = &types.Sym{Name: "."}
|
s = &types.Sym{Name: "."}
|
||||||
}
|
}
|
||||||
n := NewName(s)
|
n := NewName(s)
|
||||||
n.Type = t
|
n.SetType(t)
|
||||||
n.Xoffset = xoffset
|
n.SetOffset(xoffset)
|
||||||
n.SetClass(cl)
|
n.SetClass(cl)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -158,8 +158,8 @@ func TestCmpstackvar(t *testing.T) {
|
||||||
func TestStackvarSort(t *testing.T) {
|
func TestStackvarSort(t *testing.T) {
|
||||||
nod := func(xoffset int64, t *types.Type, s *types.Sym, cl ir.Class) *ir.Node {
|
nod := func(xoffset int64, t *types.Type, s *types.Sym, cl ir.Class) *ir.Node {
|
||||||
n := NewName(s)
|
n := NewName(s)
|
||||||
n.Type = t
|
n.SetType(t)
|
||||||
n.Xoffset = xoffset
|
n.SetOffset(xoffset)
|
||||||
n.SetClass(cl)
|
n.SetClass(cl)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -207,14 +207,14 @@ type progeffectscache struct {
|
||||||
// nor do we care about empty structs (handled by the pointer check),
|
// nor do we care about empty structs (handled by the pointer check),
|
||||||
// nor do we care about the fake PAUTOHEAP variables.
|
// nor do we care about the fake PAUTOHEAP variables.
|
||||||
func livenessShouldTrack(n *ir.Node) bool {
|
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
|
// getvariables returns the list of on-stack variables that we need to track
|
||||||
// and a map for looking up indices by *Node.
|
// and a map for looking up indices by *Node.
|
||||||
func getvariables(fn *ir.Node) ([]*ir.Node, map[*ir.Node]int32) {
|
func getvariables(fn *ir.Node) ([]*ir.Node, map[*ir.Node]int32) {
|
||||||
var vars []*ir.Node
|
var vars []*ir.Node
|
||||||
for _, n := range fn.Func.Dcl {
|
for _, n := range fn.Func().Dcl {
|
||||||
if livenessShouldTrack(n) {
|
if livenessShouldTrack(n) {
|
||||||
vars = append(vars, n)
|
vars = append(vars, n)
|
||||||
}
|
}
|
||||||
|
|
@ -272,7 +272,7 @@ const (
|
||||||
// If v does not affect any tracked variables, it returns -1, 0.
|
// If v does not affect any tracked variables, it returns -1, 0.
|
||||||
func (lv *Liveness) valueEffects(v *ssa.Value) (int32, liveEffect) {
|
func (lv *Liveness) valueEffects(v *ssa.Value) (int32, liveEffect) {
|
||||||
n, e := affectedNode(v)
|
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
|
return -1, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -282,7 +282,7 @@ func (lv *Liveness) valueEffects(v *ssa.Value) (int32, liveEffect) {
|
||||||
// variable" ICEs (issue 19632).
|
// variable" ICEs (issue 19632).
|
||||||
switch v.Op {
|
switch v.Op {
|
||||||
case ssa.OpVarDef, ssa.OpVarKill, ssa.OpVarLive, ssa.OpKeepAlive:
|
case ssa.OpVarDef, ssa.OpVarKill, ssa.OpVarLive, ssa.OpKeepAlive:
|
||||||
if !n.Name.Used() {
|
if !n.Name().Used() {
|
||||||
return -1, 0
|
return -1, 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -297,7 +297,7 @@ func (lv *Liveness) valueEffects(v *ssa.Value) (int32, liveEffect) {
|
||||||
if e&(ssa.SymRead|ssa.SymAddr) != 0 {
|
if e&(ssa.SymRead|ssa.SymAddr) != 0 {
|
||||||
effect |= uevar
|
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
|
effect |= varkill
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -491,10 +491,10 @@ func (lv *Liveness) pointerMap(liveout bvec, vars []*ir.Node, args, locals bvec)
|
||||||
node := vars[i]
|
node := vars[i]
|
||||||
switch node.Class() {
|
switch node.Class() {
|
||||||
case ir.PAUTO:
|
case ir.PAUTO:
|
||||||
onebitwalktype1(node.Type, node.Xoffset+lv.stkptrsize, locals)
|
onebitwalktype1(node.Type(), node.Offset()+lv.stkptrsize, locals)
|
||||||
|
|
||||||
case ir.PPARAM, ir.PPARAMOUT:
|
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).
|
// pointers to copy values back to the stack).
|
||||||
// TODO: if the output parameter is heap-allocated, then we
|
// TODO: if the output parameter is heap-allocated, then we
|
||||||
// don't need to keep the stack copy live?
|
// 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 {
|
for i, n := range lv.vars {
|
||||||
if n.Class() == ir.PPARAMOUT {
|
if n.Class() == ir.PPARAMOUT {
|
||||||
if n.Name.IsOutputParamHeapAddr() {
|
if n.Name().IsOutputParamHeapAddr() {
|
||||||
// Just to be paranoid. Heap addresses are PAUTOs.
|
// Just to be paranoid. Heap addresses are PAUTOs.
|
||||||
base.Fatalf("variable %v both output param and heap output param", n)
|
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
|
// If this variable moved to the heap, then
|
||||||
// its stack copy is not live.
|
// its stack copy is not live.
|
||||||
continue
|
continue
|
||||||
|
|
@ -803,21 +803,21 @@ func (lv *Liveness) epilogue() {
|
||||||
// Note: zeroing is handled by zeroResults in walk.go.
|
// Note: zeroing is handled by zeroResults in walk.go.
|
||||||
livedefer.Set(int32(i))
|
livedefer.Set(int32(i))
|
||||||
}
|
}
|
||||||
if n.Name.IsOutputParamHeapAddr() {
|
if n.Name().IsOutputParamHeapAddr() {
|
||||||
// This variable will be overwritten early in the function
|
// This variable will be overwritten early in the function
|
||||||
// prologue (from the result of a mallocgc) but we need to
|
// prologue (from the result of a mallocgc) but we need to
|
||||||
// zero it in case that malloc causes a stack scan.
|
// zero it in case that malloc causes a stack scan.
|
||||||
n.Name.SetNeedzero(true)
|
n.Name().SetNeedzero(true)
|
||||||
livedefer.Set(int32(i))
|
livedefer.Set(int32(i))
|
||||||
}
|
}
|
||||||
if n.Name.OpenDeferSlot() {
|
if n.Name().OpenDeferSlot() {
|
||||||
// Open-coded defer args slots must be live
|
// Open-coded defer args slots must be live
|
||||||
// everywhere in a function, since a panic can
|
// everywhere in a function, since a panic can
|
||||||
// occur (almost) anywhere. Because it is live
|
// occur (almost) anywhere. Because it is live
|
||||||
// everywhere, it must be zeroed on entry.
|
// everywhere, it must be zeroed on entry.
|
||||||
livedefer.Set(int32(i))
|
livedefer.Set(int32(i))
|
||||||
// It was already marked as Needzero when created.
|
// 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")
|
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 {
|
if n.Class() == ir.PPARAM {
|
||||||
continue // ok
|
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.
|
// 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 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
|
lv.livenessMap.deferreturn = LivenessDontCare
|
||||||
} else {
|
} else {
|
||||||
lv.livenessMap.deferreturn = LivenessIndex{
|
lv.livenessMap.deferreturn = LivenessIndex{
|
||||||
|
|
@ -922,7 +922,7 @@ func (lv *Liveness) epilogue() {
|
||||||
// input parameters.
|
// input parameters.
|
||||||
for j, n := range lv.vars {
|
for j, n := range lv.vars {
|
||||||
if n.Class() != ir.PPARAM && lv.stackMaps[0].Get(int32(j)) {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pos := lv.fn.Func.Nname.Pos
|
pos := lv.fn.Func().Nname.Pos()
|
||||||
if v != nil {
|
if v != nil {
|
||||||
pos = v.Pos
|
pos = v.Pos
|
||||||
}
|
}
|
||||||
|
|
@ -1024,7 +1024,7 @@ func (lv *Liveness) printbvec(printed bool, name string, live bvec) bool {
|
||||||
if !live.Get(int32(i)) {
|
if !live.Get(int32(i)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fmt.Printf("%s%s", comma, n.Sym.Name)
|
fmt.Printf("%s%s", comma, n.Sym().Name)
|
||||||
comma = ","
|
comma = ","
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
@ -1042,7 +1042,7 @@ func (lv *Liveness) printeffect(printed bool, name string, pos int32, x bool) bo
|
||||||
}
|
}
|
||||||
fmt.Printf("%s=", name)
|
fmt.Printf("%s=", name)
|
||||||
if x {
|
if x {
|
||||||
fmt.Printf("%s", lv.vars[pos].Sym.Name)
|
fmt.Printf("%s", lv.vars[pos].Sym().Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
@ -1090,7 +1090,7 @@ func (lv *Liveness) printDebug() {
|
||||||
|
|
||||||
if b == lv.f.Entry {
|
if b == lv.f.Entry {
|
||||||
live := lv.stackMaps[0]
|
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=")
|
fmt.Printf("\tlive=")
|
||||||
printed = false
|
printed = false
|
||||||
for j, n := range lv.vars {
|
for j, n := range lv.vars {
|
||||||
|
|
@ -1168,7 +1168,7 @@ func (lv *Liveness) emit() (argsSym, liveSym *obj.LSym) {
|
||||||
for _, n := range lv.vars {
|
for _, n := range lv.vars {
|
||||||
switch n.Class() {
|
switch n.Class() {
|
||||||
case ir.PPARAM, ir.PPARAMOUT:
|
case ir.PPARAM, ir.PPARAMOUT:
|
||||||
if maxArgNode == nil || n.Xoffset > maxArgNode.Xoffset {
|
if maxArgNode == nil || n.Offset() > maxArgNode.Offset() {
|
||||||
maxArgNode = n
|
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.
|
// Next, find the offset of the largest pointer in the largest node.
|
||||||
var maxArgs int64
|
var maxArgs int64
|
||||||
if maxArgNode != nil {
|
if maxArgNode != nil {
|
||||||
maxArgs = maxArgNode.Xoffset + typeptrdata(maxArgNode.Type)
|
maxArgs = maxArgNode.Offset() + typeptrdata(maxArgNode.Type())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size locals bitmaps to be stkptrsize sized.
|
// 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
|
// Emit the live pointer map data structures
|
||||||
ls := e.curfn.Func.LSym
|
ls := e.curfn.Func().LSym
|
||||||
fninfo := ls.Func()
|
fninfo := ls.Func()
|
||||||
fninfo.GCArgs, fninfo.GCLocals = lv.emit()
|
fninfo.GCArgs, fninfo.GCLocals = lv.emit()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,12 +61,12 @@ func ispkgin(pkgs []string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func instrument(fn *ir.Node) {
|
func instrument(fn *ir.Node) {
|
||||||
if fn.Func.Pragma&ir.Norace != 0 {
|
if fn.Func().Pragma&ir.Norace != 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !base.Flag.Race || !ispkgin(norace_inst_pkgs) {
|
if !base.Flag.Race || !ispkgin(norace_inst_pkgs) {
|
||||||
fn.Func.SetInstrumentBody(true)
|
fn.Func().SetInstrumentBody(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if base.Flag.Race {
|
if base.Flag.Race {
|
||||||
|
|
@ -74,8 +74,8 @@ func instrument(fn *ir.Node) {
|
||||||
base.Pos = src.NoXPos
|
base.Pos = src.NoXPos
|
||||||
|
|
||||||
if thearch.LinkArch.Arch.Family != sys.AMD64 {
|
if thearch.LinkArch.Arch.Family != sys.AMD64 {
|
||||||
fn.Func.Enter.Prepend(mkcall("racefuncenterfp", nil, nil))
|
fn.Func().Enter.Prepend(mkcall("racefuncenterfp", nil, nil))
|
||||||
fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil))
|
fn.Func().Exit.Append(mkcall("racefuncexit", nil, nil))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// nodpc is the PC of the caller as extracted by
|
// 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
|
// work on arm or others that might support
|
||||||
// race in the future.
|
// race in the future.
|
||||||
nodpc := ir.Copy(nodfp)
|
nodpc := ir.Copy(nodfp)
|
||||||
nodpc.Type = types.Types[types.TUINTPTR]
|
nodpc.SetType(types.Types[types.TUINTPTR])
|
||||||
nodpc.Xoffset = int64(-Widthptr)
|
nodpc.SetOffset(int64(-Widthptr))
|
||||||
fn.Func.Dcl = append(fn.Func.Dcl, nodpc)
|
fn.Func().Dcl = append(fn.Func().Dcl, nodpc)
|
||||||
fn.Func.Enter.Prepend(mkcall("racefuncenter", nil, nil, nodpc))
|
fn.Func().Enter.Prepend(mkcall("racefuncenter", nil, nil, nodpc))
|
||||||
fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil))
|
fn.Func().Exit.Append(mkcall("racefuncexit", nil, nil))
|
||||||
}
|
}
|
||||||
base.Pos = lno
|
base.Pos = lno
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ func typecheckrange(n *ir.Node) {
|
||||||
|
|
||||||
// second half of dance, the first half being typecheckrangeExpr
|
// second half of dance, the first half being typecheckrangeExpr
|
||||||
n.SetTypecheck(1)
|
n.SetTypecheck(1)
|
||||||
ls := n.List.Slice()
|
ls := n.List().Slice()
|
||||||
for i1, n1 := range ls {
|
for i1, n1 := range ls {
|
||||||
if n1.Typecheck() == 0 {
|
if n1.Typecheck() == 0 {
|
||||||
ls[i1] = typecheck(ls[i1], ctxExpr|ctxAssign)
|
ls[i1] = typecheck(ls[i1], ctxExpr|ctxAssign)
|
||||||
|
|
@ -35,21 +35,21 @@ func typecheckrange(n *ir.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
decldepth++
|
decldepth++
|
||||||
typecheckslice(n.Nbody.Slice(), ctxStmt)
|
typecheckslice(n.Body().Slice(), ctxStmt)
|
||||||
decldepth--
|
decldepth--
|
||||||
}
|
}
|
||||||
|
|
||||||
func typecheckrangeExpr(n *ir.Node) {
|
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 {
|
if t == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// delicate little dance. see typecheckas2
|
// delicate little dance. see typecheckas2
|
||||||
ls := n.List.Slice()
|
ls := n.List().Slice()
|
||||||
for i1, n1 := range ls {
|
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)
|
ls[i1] = typecheck(ls[i1], ctxExpr|ctxAssign)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -57,13 +57,13 @@ func typecheckrangeExpr(n *ir.Node) {
|
||||||
if t.IsPtr() && t.Elem().IsArray() {
|
if t.IsPtr() && t.Elem().IsArray() {
|
||||||
t = t.Elem()
|
t = t.Elem()
|
||||||
}
|
}
|
||||||
n.Type = t
|
n.SetType(t)
|
||||||
|
|
||||||
var t1, t2 *types.Type
|
var t1, t2 *types.Type
|
||||||
toomany := false
|
toomany := false
|
||||||
switch t.Etype {
|
switch t.Etype {
|
||||||
default:
|
default:
|
||||||
base.ErrorfAt(n.Pos, "cannot range over %L", n.Right)
|
base.ErrorfAt(n.Pos(), "cannot range over %L", n.Right())
|
||||||
return
|
return
|
||||||
|
|
||||||
case types.TARRAY, types.TSLICE:
|
case types.TARRAY, types.TSLICE:
|
||||||
|
|
@ -76,13 +76,13 @@ func typecheckrangeExpr(n *ir.Node) {
|
||||||
|
|
||||||
case types.TCHAN:
|
case types.TCHAN:
|
||||||
if !t.ChanDir().CanRecv() {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
t1 = t.Elem()
|
t1 = t.Elem()
|
||||||
t2 = nil
|
t2 = nil
|
||||||
if n.List.Len() == 2 {
|
if n.List().Len() == 2 {
|
||||||
toomany = true
|
toomany = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,16 +91,16 @@ func typecheckrangeExpr(n *ir.Node) {
|
||||||
t2 = types.Runetype
|
t2 = types.Runetype
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.List.Len() > 2 || toomany {
|
if n.List().Len() > 2 || toomany {
|
||||||
base.ErrorfAt(n.Pos, "too many variables in range")
|
base.ErrorfAt(n.Pos(), "too many variables in range")
|
||||||
}
|
}
|
||||||
|
|
||||||
var v1, v2 *ir.Node
|
var v1, v2 *ir.Node
|
||||||
if n.List.Len() != 0 {
|
if n.List().Len() != 0 {
|
||||||
v1 = n.List.First()
|
v1 = n.List().First()
|
||||||
}
|
}
|
||||||
if n.List.Len() > 1 {
|
if n.List().Len() > 1 {
|
||||||
v2 = n.List.Second()
|
v2 = n.List().Second()
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is not only an optimization but also a requirement in the spec.
|
// this is not only an optimization but also a requirement in the spec.
|
||||||
|
|
@ -109,28 +109,28 @@ func typecheckrangeExpr(n *ir.Node) {
|
||||||
// present."
|
// present."
|
||||||
if ir.IsBlank(v2) {
|
if ir.IsBlank(v2) {
|
||||||
if v1 != nil {
|
if v1 != nil {
|
||||||
n.List.Set1(v1)
|
n.PtrList().Set1(v1)
|
||||||
}
|
}
|
||||||
v2 = nil
|
v2 = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if v1 != nil {
|
if v1 != nil {
|
||||||
if v1.Name != nil && v1.Name.Defn == n {
|
if v1.Name() != nil && v1.Name().Defn == n {
|
||||||
v1.Type = t1
|
v1.SetType(t1)
|
||||||
} else if v1.Type != nil {
|
} else if v1.Type() != nil {
|
||||||
if op, why := assignop(t1, v1.Type); op == ir.OXXX {
|
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)
|
base.ErrorfAt(n.Pos(), "cannot assign type %v to %L in range%s", t1, v1, why)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkassign(n, v1)
|
checkassign(n, v1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if v2 != nil {
|
if v2 != nil {
|
||||||
if v2.Name != nil && v2.Name.Defn == n {
|
if v2.Name() != nil && v2.Name().Defn == n {
|
||||||
v2.Type = t2
|
v2.SetType(t2)
|
||||||
} else if v2.Type != nil {
|
} else if v2.Type() != nil {
|
||||||
if op, why := assignop(t2, v2.Type); op == ir.OXXX {
|
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)
|
base.ErrorfAt(n.Pos(), "cannot assign type %v to %L in range%s", t2, v2, why)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkassign(n, v2)
|
checkassign(n, v2)
|
||||||
|
|
@ -159,7 +159,7 @@ func cheapComputableIndex(width int64) bool {
|
||||||
// the returned node.
|
// the returned node.
|
||||||
func walkrange(n *ir.Node) *ir.Node {
|
func walkrange(n *ir.Node) *ir.Node {
|
||||||
if isMapClear(n) {
|
if isMapClear(n) {
|
||||||
m := n.Right
|
m := n.Right()
|
||||||
lno := setlineno(m)
|
lno := setlineno(m)
|
||||||
n = mapClear(m)
|
n = mapClear(m)
|
||||||
base.Pos = lno
|
base.Pos = lno
|
||||||
|
|
@ -173,20 +173,20 @@ func walkrange(n *ir.Node) *ir.Node {
|
||||||
// hb: hidden bool
|
// hb: hidden bool
|
||||||
// a, v1, v2: not hidden aggregate, val 1, 2
|
// a, v1, v2: not hidden aggregate, val 1, 2
|
||||||
|
|
||||||
t := n.Type
|
t := n.Type()
|
||||||
|
|
||||||
a := n.Right
|
a := n.Right()
|
||||||
lno := setlineno(a)
|
lno := setlineno(a)
|
||||||
n.Right = nil
|
n.SetRight(nil)
|
||||||
|
|
||||||
var v1, v2 *ir.Node
|
var v1, v2 *ir.Node
|
||||||
l := n.List.Len()
|
l := n.List().Len()
|
||||||
if l > 0 {
|
if l > 0 {
|
||||||
v1 = n.List.First()
|
v1 = n.List().First()
|
||||||
}
|
}
|
||||||
|
|
||||||
if l > 1 {
|
if l > 1 {
|
||||||
v2 = n.List.Second()
|
v2 = n.List().Second()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ir.IsBlank(v2) {
|
if ir.IsBlank(v2) {
|
||||||
|
|
@ -203,7 +203,7 @@ func walkrange(n *ir.Node) *ir.Node {
|
||||||
|
|
||||||
// n.List has no meaning anymore, clear it
|
// n.List has no meaning anymore, clear it
|
||||||
// to avoid erroneous processing by racewalk.
|
// to avoid erroneous processing by racewalk.
|
||||||
n.List.Set(nil)
|
n.PtrList().Set(nil)
|
||||||
|
|
||||||
var ifGuard *ir.Node
|
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, hv1, nil))
|
||||||
init = append(init, ir.Nod(ir.OAS, hn, ir.Nod(ir.OLEN, ha, nil)))
|
init = append(init, ir.Nod(ir.OAS, hn, ir.Nod(ir.OLEN, ha, nil)))
|
||||||
|
|
||||||
n.Left = ir.Nod(ir.OLT, hv1, hn)
|
n.SetLeft(ir.Nod(ir.OLT, hv1, hn))
|
||||||
n.Right = ir.Nod(ir.OAS, hv1, ir.Nod(ir.OADD, hv1, nodintconst(1)))
|
n.SetRight(ir.Nod(ir.OAS, hv1, ir.Nod(ir.OADD, hv1, nodintconst(1))))
|
||||||
|
|
||||||
// for range ha { body }
|
// for range ha { body }
|
||||||
if v1 == nil {
|
if v1 == nil {
|
||||||
|
|
@ -245,15 +245,15 @@ func walkrange(n *ir.Node) *ir.Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
// for v1, v2 := range ha { body }
|
// for v1, v2 := range ha { body }
|
||||||
if cheapComputableIndex(n.Type.Elem().Width) {
|
if cheapComputableIndex(n.Type().Elem().Width) {
|
||||||
// v1, v2 = hv1, ha[hv1]
|
// v1, v2 = hv1, ha[hv1]
|
||||||
tmp := ir.Nod(ir.OINDEX, ha, hv1)
|
tmp := ir.Nod(ir.OINDEX, ha, hv1)
|
||||||
tmp.SetBounded(true)
|
tmp.SetBounded(true)
|
||||||
// Use OAS2 to correctly handle assignments
|
// Use OAS2 to correctly handle assignments
|
||||||
// of the form "v1, a[v1] := range".
|
// of the form "v1, a[v1] := range".
|
||||||
a := ir.Nod(ir.OAS2, nil, nil)
|
a := ir.Nod(ir.OAS2, nil, nil)
|
||||||
a.List.Set2(v1, v2)
|
a.PtrList().Set2(v1, v2)
|
||||||
a.Rlist.Set2(hv1, tmp)
|
a.PtrRlist().Set2(hv1, tmp)
|
||||||
body = []*ir.Node{a}
|
body = []*ir.Node{a}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -271,10 +271,10 @@ func walkrange(n *ir.Node) *ir.Node {
|
||||||
// elimination on the index variable (see #20711).
|
// elimination on the index variable (see #20711).
|
||||||
// Enhance the prove pass to understand this.
|
// Enhance the prove pass to understand this.
|
||||||
ifGuard = ir.Nod(ir.OIF, nil, nil)
|
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
|
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 := ir.Nod(ir.OINDEX, ha, nodintconst(0))
|
||||||
tmp.SetBounded(true)
|
tmp.SetBounded(true)
|
||||||
init = append(init, ir.Nod(ir.OAS, hp, ir.Nod(ir.OADDR, tmp, nil)))
|
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
|
// Use OAS2 to correctly handle assignments
|
||||||
// of the form "v1, a[v1] := range".
|
// of the form "v1, a[v1] := range".
|
||||||
a := ir.Nod(ir.OAS2, nil, nil)
|
a := ir.Nod(ir.OAS2, nil, nil)
|
||||||
a.List.Set2(v1, v2)
|
a.PtrList().Set2(v1, v2)
|
||||||
a.Rlist.Set2(hv1, ir.Nod(ir.ODEREF, hp, nil))
|
a.PtrRlist().Set2(hv1, ir.Nod(ir.ODEREF, hp, nil))
|
||||||
body = append(body, a)
|
body = append(body, a)
|
||||||
|
|
||||||
// Advance pointer as part of the late increment.
|
// Advance pointer as part of the late increment.
|
||||||
|
|
@ -293,7 +293,7 @@ func walkrange(n *ir.Node) *ir.Node {
|
||||||
// end of the allocation.
|
// end of the allocation.
|
||||||
a = ir.Nod(ir.OAS, hp, addptr(hp, t.Elem().Width))
|
a = ir.Nod(ir.OAS, hp, addptr(hp, t.Elem().Width))
|
||||||
a = typecheck(a, ctxStmt)
|
a = typecheck(a, ctxStmt)
|
||||||
n.List.Set1(a)
|
n.PtrList().Set1(a)
|
||||||
|
|
||||||
case types.TMAP:
|
case types.TMAP:
|
||||||
// order.stmt allocated the iterator for us.
|
// order.stmt allocated the iterator for us.
|
||||||
|
|
@ -301,8 +301,8 @@ func walkrange(n *ir.Node) *ir.Node {
|
||||||
ha := a
|
ha := a
|
||||||
|
|
||||||
hit := prealloc[n]
|
hit := prealloc[n]
|
||||||
th := hit.Type
|
th := hit.Type()
|
||||||
n.Left = nil
|
n.SetLeft(nil)
|
||||||
keysym := th.Field(0).Sym // depends on layout of iterator struct. See reflect.go:hiter
|
keysym := th.Field(0).Sym // depends on layout of iterator struct. See reflect.go:hiter
|
||||||
elemsym := th.Field(1).Sym // ditto
|
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)
|
fn = substArgTypes(fn, t.Key(), t.Elem(), th)
|
||||||
init = append(init, mkcall1(fn, nil, nil, typename(t), ha, ir.Nod(ir.OADDR, hit, nil)))
|
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 = syslook("mapiternext")
|
||||||
fn = substArgTypes(fn, th)
|
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 := nodSym(ir.ODOT, hit, keysym)
|
||||||
key = ir.Nod(ir.ODEREF, key, nil)
|
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 := nodSym(ir.ODOT, hit, elemsym)
|
||||||
elem = ir.Nod(ir.ODEREF, elem, nil)
|
elem = ir.Nod(ir.ODEREF, elem, nil)
|
||||||
a := ir.Nod(ir.OAS2, nil, nil)
|
a := ir.Nod(ir.OAS2, nil, nil)
|
||||||
a.List.Set2(v1, v2)
|
a.PtrList().Set2(v1, v2)
|
||||||
a.Rlist.Set2(key, elem)
|
a.PtrRlist().Set2(key, elem)
|
||||||
body = []*ir.Node{a}
|
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.
|
// order.stmt arranged for a copy of the channel variable.
|
||||||
ha := a
|
ha := a
|
||||||
|
|
||||||
n.Left = nil
|
n.SetLeft(nil)
|
||||||
|
|
||||||
hv1 := temp(t.Elem())
|
hv1 := temp(t.Elem())
|
||||||
hv1.SetTypecheck(1)
|
hv1.SetTypecheck(1)
|
||||||
|
|
@ -344,12 +344,12 @@ func walkrange(n *ir.Node) *ir.Node {
|
||||||
}
|
}
|
||||||
hb := temp(types.Types[types.TBOOL])
|
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 := ir.Nod(ir.OAS2RECV, nil, nil)
|
||||||
a.SetTypecheck(1)
|
a.SetTypecheck(1)
|
||||||
a.List.Set2(hv1, hb)
|
a.PtrList().Set2(hv1, hb)
|
||||||
a.Right = ir.Nod(ir.ORECV, ha, nil)
|
a.SetRight(ir.Nod(ir.ORECV, ha, nil))
|
||||||
n.Left.Ninit.Set1(a)
|
n.Left().PtrInit().Set1(a)
|
||||||
if v1 == nil {
|
if v1 == nil {
|
||||||
body = nil
|
body = nil
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -387,7 +387,7 @@ func walkrange(n *ir.Node) *ir.Node {
|
||||||
init = append(init, ir.Nod(ir.OAS, hv1, nil))
|
init = append(init, ir.Nod(ir.OAS, hv1, nil))
|
||||||
|
|
||||||
// hv1 < len(ha)
|
// 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 {
|
if v1 != nil {
|
||||||
// hv1t = hv1
|
// hv1t = hv1
|
||||||
|
|
@ -401,19 +401,19 @@ func walkrange(n *ir.Node) *ir.Node {
|
||||||
|
|
||||||
// if hv2 < utf8.RuneSelf
|
// if hv2 < utf8.RuneSelf
|
||||||
nif := ir.Nod(ir.OIF, nil, nil)
|
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++
|
// 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 {
|
// } else {
|
||||||
eif := ir.Nod(ir.OAS2, nil, nil)
|
eif := ir.Nod(ir.OAS2, nil, nil)
|
||||||
nif.Rlist.Set1(eif)
|
nif.PtrRlist().Set1(eif)
|
||||||
|
|
||||||
// hv2, hv1 = decoderune(ha, hv1)
|
// hv2, hv1 = decoderune(ha, hv1)
|
||||||
eif.List.Set2(hv2, hv1)
|
eif.PtrList().Set2(hv2, hv1)
|
||||||
fn := syslook("decoderune")
|
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)
|
body = append(body, nif)
|
||||||
|
|
||||||
|
|
@ -421,8 +421,8 @@ func walkrange(n *ir.Node) *ir.Node {
|
||||||
if v2 != nil {
|
if v2 != nil {
|
||||||
// v1, v2 = hv1t, hv2
|
// v1, v2 = hv1t, hv2
|
||||||
a := ir.Nod(ir.OAS2, nil, nil)
|
a := ir.Nod(ir.OAS2, nil, nil)
|
||||||
a.List.Set2(v1, v2)
|
a.PtrList().Set2(v1, v2)
|
||||||
a.Rlist.Set2(hv1t, hv2)
|
a.PtrRlist().Set2(hv1t, hv2)
|
||||||
body = append(body, a)
|
body = append(body, a)
|
||||||
} else {
|
} else {
|
||||||
// v1 = hv1t
|
// v1 = hv1t
|
||||||
|
|
@ -431,26 +431,26 @@ func walkrange(n *ir.Node) *ir.Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Op = translatedLoopOp
|
n.SetOp(translatedLoopOp)
|
||||||
typecheckslice(init, ctxStmt)
|
typecheckslice(init, ctxStmt)
|
||||||
|
|
||||||
if ifGuard != nil {
|
if ifGuard != nil {
|
||||||
ifGuard.Ninit.Append(init...)
|
ifGuard.PtrInit().Append(init...)
|
||||||
ifGuard = typecheck(ifGuard, ctxStmt)
|
ifGuard = typecheck(ifGuard, ctxStmt)
|
||||||
} else {
|
} 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.SetLeft(typecheck(n.Left(), ctxExpr))
|
||||||
n.Left = defaultlit(n.Left, nil)
|
n.SetLeft(defaultlit(n.Left(), nil))
|
||||||
n.Right = typecheck(n.Right, ctxStmt)
|
n.SetRight(typecheck(n.Right(), ctxStmt))
|
||||||
typecheckslice(body, ctxStmt)
|
typecheckslice(body, ctxStmt)
|
||||||
n.Nbody.Prepend(body...)
|
n.PtrBody().Prepend(body...)
|
||||||
|
|
||||||
if ifGuard != nil {
|
if ifGuard != nil {
|
||||||
ifGuard.Nbody.Set1(n)
|
ifGuard.PtrBody().Set1(n)
|
||||||
n = ifGuard
|
n = ifGuard
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -472,36 +472,36 @@ func isMapClear(n *ir.Node) bool {
|
||||||
return false
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
k := n.List.First()
|
k := n.List().First()
|
||||||
if k == nil || ir.IsBlank(k) {
|
if k == nil || ir.IsBlank(k) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Require k to be a new variable name.
|
// 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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Nbody.Len() != 1 {
|
if n.Body().Len() != 1 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt := n.Nbody.First() // only stmt in body
|
stmt := n.Body().First() // only stmt in body
|
||||||
if stmt == nil || stmt.Op != ir.ODELETE {
|
if stmt == nil || stmt.Op() != ir.ODELETE {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
m := n.Right
|
m := n.Right()
|
||||||
if !samesafeexpr(stmt.List.First(), m) || !samesafeexpr(stmt.List.Second(), k) {
|
if !samesafeexpr(stmt.List().First(), m) || !samesafeexpr(stmt.List().Second(), k) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keys where equality is not reflexive can not be deleted from maps.
|
// Keys where equality is not reflexive can not be deleted from maps.
|
||||||
if !isreflexive(m.Type.Key()) {
|
if !isreflexive(m.Type().Key()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -510,7 +510,7 @@ func isMapClear(n *ir.Node) bool {
|
||||||
|
|
||||||
// mapClear constructs a call to runtime.mapclear for the map m.
|
// mapClear constructs a call to runtime.mapclear for the map m.
|
||||||
func mapClear(m *ir.Node) *ir.Node {
|
func mapClear(m *ir.Node) *ir.Node {
|
||||||
t := m.Type
|
t := m.Type()
|
||||||
|
|
||||||
// instantiate mapclear(typ *type, hmap map[any]any)
|
// instantiate mapclear(typ *type, hmap map[any]any)
|
||||||
fn := syslook("mapclear")
|
fn := syslook("mapclear")
|
||||||
|
|
@ -543,21 +543,21 @@ func arrayClear(n, v1, v2, a *ir.Node) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Nbody.Len() != 1 || n.Nbody.First() == nil {
|
if n.Body().Len() != 1 || n.Body().First() == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt := n.Nbody.First() // only stmt in body
|
stmt := n.Body().First() // only stmt in body
|
||||||
if stmt.Op != ir.OAS || stmt.Left.Op != ir.OINDEX {
|
if stmt.Op() != ir.OAS || stmt.Left().Op() != ir.OINDEX {
|
||||||
return false
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
elemsize := n.Type.Elem().Width
|
elemsize := n.Type().Elem().Width
|
||||||
if elemsize <= 0 || !isZero(stmt.Right) {
|
if elemsize <= 0 || !isZero(stmt.Right()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -568,10 +568,10 @@ func arrayClear(n, v1, v2, a *ir.Node) bool {
|
||||||
// memclr{NoHeap,Has}Pointers(hp, hn)
|
// memclr{NoHeap,Has}Pointers(hp, hn)
|
||||||
// i = len(a) - 1
|
// i = len(a) - 1
|
||||||
// }
|
// }
|
||||||
n.Op = ir.OIF
|
n.SetOp(ir.OIF)
|
||||||
|
|
||||||
n.Nbody.Set(nil)
|
n.PtrBody().Set(nil)
|
||||||
n.Left = ir.Nod(ir.ONE, ir.Nod(ir.OLEN, a, nil), nodintconst(0))
|
n.SetLeft(ir.Nod(ir.ONE, ir.Nod(ir.OLEN, a, nil), nodintconst(0)))
|
||||||
|
|
||||||
// hp = &a[0]
|
// hp = &a[0]
|
||||||
hp := temp(types.Types[types.TUNSAFEPTR])
|
hp := temp(types.Types[types.TUNSAFEPTR])
|
||||||
|
|
@ -580,7 +580,7 @@ func arrayClear(n, v1, v2, a *ir.Node) bool {
|
||||||
tmp.SetBounded(true)
|
tmp.SetBounded(true)
|
||||||
tmp = ir.Nod(ir.OADDR, tmp, nil)
|
tmp = ir.Nod(ir.OADDR, tmp, nil)
|
||||||
tmp = convnop(tmp, types.Types[types.TUNSAFEPTR])
|
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 = len(a) * sizeof(elem(a))
|
||||||
hn := temp(types.Types[types.TUINTPTR])
|
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.OLEN, a, nil)
|
||||||
tmp = ir.Nod(ir.OMUL, tmp, nodintconst(elemsize))
|
tmp = ir.Nod(ir.OMUL, tmp, nodintconst(elemsize))
|
||||||
tmp = conv(tmp, types.Types[types.TUINTPTR])
|
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
|
var fn *ir.Node
|
||||||
if a.Type.Elem().HasPointers() {
|
if a.Type().Elem().HasPointers() {
|
||||||
// memclrHasPointers(hp, hn)
|
// memclrHasPointers(hp, hn)
|
||||||
Curfn.Func.SetWBPos(stmt.Pos)
|
Curfn.Func().SetWBPos(stmt.Pos())
|
||||||
fn = mkcall("memclrHasPointers", nil, nil, hp, hn)
|
fn = mkcall("memclrHasPointers", nil, nil, hp, hn)
|
||||||
} else {
|
} else {
|
||||||
// memclrNoHeapPointers(hp, hn)
|
// memclrNoHeapPointers(hp, hn)
|
||||||
fn = mkcall("memclrNoHeapPointers", nil, nil, hp, hn)
|
fn = mkcall("memclrNoHeapPointers", nil, nil, hp, hn)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Nbody.Append(fn)
|
n.PtrBody().Append(fn)
|
||||||
|
|
||||||
// i = len(a) - 1
|
// i = len(a) - 1
|
||||||
v1 = ir.Nod(ir.OAS, v1, ir.Nod(ir.OSUB, ir.Nod(ir.OLEN, a, nil), nodintconst(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.SetLeft(typecheck(n.Left(), ctxExpr))
|
||||||
n.Left = defaultlit(n.Left, nil)
|
n.SetLeft(defaultlit(n.Left(), nil))
|
||||||
typecheckslice(n.Nbody.Slice(), ctxStmt)
|
typecheckslice(n.Body().Slice(), ctxStmt)
|
||||||
n = walkstmt(n)
|
n = walkstmt(n)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// addptr returns (*T)(uintptr(p) + n).
|
// addptr returns (*T)(uintptr(p) + n).
|
||||||
func addptr(p *ir.Node, n int64) *ir.Node {
|
func addptr(p *ir.Node, n int64) *ir.Node {
|
||||||
t := p.Type
|
t := p.Type()
|
||||||
|
|
||||||
p = ir.Nod(ir.OCONVNOP, p, nil)
|
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.OADD, p, nodintconst(n))
|
||||||
|
|
||||||
p = ir.Nod(ir.OCONVNOP, p, nil)
|
p = ir.Nod(ir.OCONVNOP, p, nil)
|
||||||
p.Type = t
|
p.SetType(t)
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -994,14 +994,14 @@ func typename(t *types.Type) *ir.Node {
|
||||||
s := typenamesym(t)
|
s := typenamesym(t)
|
||||||
if s.Def == nil {
|
if s.Def == nil {
|
||||||
n := ir.NewNameAt(src.NoXPos, s)
|
n := ir.NewNameAt(src.NoXPos, s)
|
||||||
n.Type = types.Types[types.TUINT8]
|
n.SetType(types.Types[types.TUINT8])
|
||||||
n.SetClass(ir.PEXTERN)
|
n.SetClass(ir.PEXTERN)
|
||||||
n.SetTypecheck(1)
|
n.SetTypecheck(1)
|
||||||
s.Def = ir.AsTypesNode(n)
|
s.Def = ir.AsTypesNode(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
n := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil)
|
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)
|
n.SetTypecheck(1)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -1013,7 +1013,7 @@ func itabname(t, itype *types.Type) *ir.Node {
|
||||||
s := itabpkg.Lookup(t.ShortString() + "," + itype.ShortString())
|
s := itabpkg.Lookup(t.ShortString() + "," + itype.ShortString())
|
||||||
if s.Def == nil {
|
if s.Def == nil {
|
||||||
n := NewName(s)
|
n := NewName(s)
|
||||||
n.Type = types.Types[types.TUINT8]
|
n.SetType(types.Types[types.TUINT8])
|
||||||
n.SetClass(ir.PEXTERN)
|
n.SetClass(ir.PEXTERN)
|
||||||
n.SetTypecheck(1)
|
n.SetTypecheck(1)
|
||||||
s.Def = ir.AsTypesNode(n)
|
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 := 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)
|
n.SetTypecheck(1)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -1519,8 +1519,8 @@ func addsignat(t *types.Type) {
|
||||||
func addsignats(dcls []*ir.Node) {
|
func addsignats(dcls []*ir.Node) {
|
||||||
// copy types from dcl list to signatset
|
// copy types from dcl list to signatset
|
||||||
for _, n := range dcls {
|
for _, n := range dcls {
|
||||||
if n.Op == ir.OTYPE {
|
if n.Op() == ir.OTYPE {
|
||||||
addsignat(n.Type)
|
addsignat(n.Type())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1879,13 +1879,13 @@ func zeroaddr(size int64) *ir.Node {
|
||||||
s := mappkg.Lookup("zero")
|
s := mappkg.Lookup("zero")
|
||||||
if s.Def == nil {
|
if s.Def == nil {
|
||||||
x := NewName(s)
|
x := NewName(s)
|
||||||
x.Type = types.Types[types.TUINT8]
|
x.SetType(types.Types[types.TUINT8])
|
||||||
x.SetClass(ir.PEXTERN)
|
x.SetClass(ir.PEXTERN)
|
||||||
x.SetTypecheck(1)
|
x.SetTypecheck(1)
|
||||||
s.Def = ir.AsTypesNode(x)
|
s.Def = ir.AsTypesNode(x)
|
||||||
}
|
}
|
||||||
z := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil)
|
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)
|
z.SetTypecheck(1)
|
||||||
return z
|
return z
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ func visitBottomUp(list []*ir.Node, analyze func(list []*ir.Node, recursive bool
|
||||||
v.analyze = analyze
|
v.analyze = analyze
|
||||||
v.nodeID = make(map[*ir.Node]uint32)
|
v.nodeID = make(map[*ir.Node]uint32)
|
||||||
for _, n := range list {
|
for _, n := range list {
|
||||||
if n.Op == ir.ODCLFUNC && !n.Func.IsHiddenClosure() {
|
if n.Op() == ir.ODCLFUNC && !n.Func().IsHiddenClosure() {
|
||||||
v.visit(n)
|
v.visit(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -75,46 +75,46 @@ func (v *bottomUpVisitor) visit(n *ir.Node) uint32 {
|
||||||
min := v.visitgen
|
min := v.visitgen
|
||||||
v.stack = append(v.stack, n)
|
v.stack = append(v.stack, n)
|
||||||
|
|
||||||
ir.InspectList(n.Nbody, func(n *ir.Node) bool {
|
ir.InspectList(n.Body(), func(n *ir.Node) bool {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.ONAME:
|
case ir.ONAME:
|
||||||
if n.Class() == ir.PFUNC {
|
if n.Class() == ir.PFUNC {
|
||||||
if n != nil && n.Name.Defn != nil {
|
if n != nil && n.Name().Defn != nil {
|
||||||
if m := v.visit(n.Name.Defn); m < min {
|
if m := v.visit(n.Name().Defn); m < min {
|
||||||
min = m
|
min = m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ir.OMETHEXPR:
|
case ir.OMETHEXPR:
|
||||||
fn := methodExprName(n)
|
fn := methodExprName(n)
|
||||||
if fn != nil && fn.Name.Defn != nil {
|
if fn != nil && fn.Name().Defn != nil {
|
||||||
if m := v.visit(fn.Name.Defn); m < min {
|
if m := v.visit(fn.Name().Defn); m < min {
|
||||||
min = m
|
min = m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ir.ODOTMETH:
|
case ir.ODOTMETH:
|
||||||
fn := methodExprName(n)
|
fn := methodExprName(n)
|
||||||
if fn != nil && fn.Op == ir.ONAME && fn.Class() == ir.PFUNC && fn.Name.Defn != nil {
|
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 m := v.visit(fn.Name().Defn); m < min {
|
||||||
min = m
|
min = m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ir.OCALLPART:
|
case ir.OCALLPART:
|
||||||
fn := ir.AsNode(callpartMethod(n).Nname)
|
fn := ir.AsNode(callpartMethod(n).Nname)
|
||||||
if fn != nil && fn.Op == ir.ONAME && fn.Class() == ir.PFUNC && fn.Name.Defn != nil {
|
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 m := v.visit(fn.Name().Defn); m < min {
|
||||||
min = m
|
min = m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ir.OCLOSURE:
|
case ir.OCLOSURE:
|
||||||
if m := v.visit(n.Func.Decl); m < min {
|
if m := v.visit(n.Func().Decl); m < min {
|
||||||
min = m
|
min = m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
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.
|
// This node is the root of a strongly connected component.
|
||||||
|
|
||||||
// The original min passed to visitcodelist was v.nodeID[n]+1.
|
// The original min passed to visitcodelist was v.nodeID[n]+1.
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
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.
|
// Initialize the DWARF scope tree based on lexical scopes.
|
||||||
dwarfScopes := make([]dwarf.Scope, 1+len(fn.Func.Parents))
|
dwarfScopes := make([]dwarf.Scope, 1+len(fn.Func().Parents))
|
||||||
for i, parent := range fn.Func.Parents {
|
for i, parent := range fn.Func().Parents {
|
||||||
dwarfScopes[i+1].Parent = int32(parent)
|
dwarfScopes[i+1].Parent = int32(parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
scopeVariables(dwarfVars, varScopes, dwarfScopes)
|
scopeVariables(dwarfVars, varScopes, dwarfScopes)
|
||||||
scopePCs(fnsym, fn.Func.Marks, dwarfScopes)
|
scopePCs(fnsym, fn.Func().Marks, dwarfScopes)
|
||||||
return compactScopes(dwarfScopes)
|
return compactScopes(dwarfScopes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,36 +14,36 @@ import (
|
||||||
func typecheckselect(sel *ir.Node) {
|
func typecheckselect(sel *ir.Node) {
|
||||||
var def *ir.Node
|
var def *ir.Node
|
||||||
lno := setlineno(sel)
|
lno := setlineno(sel)
|
||||||
typecheckslice(sel.Ninit.Slice(), ctxStmt)
|
typecheckslice(sel.Init().Slice(), ctxStmt)
|
||||||
for _, ncase := range sel.List.Slice() {
|
for _, ncase := range sel.List().Slice() {
|
||||||
if ncase.Op != ir.OCASE {
|
if ncase.Op() != ir.OCASE {
|
||||||
setlineno(ncase)
|
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
|
// default
|
||||||
if def != nil {
|
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 {
|
} else {
|
||||||
def = ncase
|
def = ncase
|
||||||
}
|
}
|
||||||
} else if ncase.List.Len() > 1 {
|
} else if ncase.List().Len() > 1 {
|
||||||
base.ErrorfAt(ncase.Pos, "select cases cannot be lists")
|
base.ErrorfAt(ncase.Pos(), "select cases cannot be lists")
|
||||||
} else {
|
} else {
|
||||||
ncase.List.SetFirst(typecheck(ncase.List.First(), ctxStmt))
|
ncase.List().SetFirst(typecheck(ncase.List().First(), ctxStmt))
|
||||||
n := ncase.List.First()
|
n := ncase.List().First()
|
||||||
ncase.Left = n
|
ncase.SetLeft(n)
|
||||||
ncase.List.Set(nil)
|
ncase.PtrList().Set(nil)
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
default:
|
default:
|
||||||
pos := n.Pos
|
pos := n.Pos()
|
||||||
if n.Op == ir.ONAME {
|
if n.Op() == ir.ONAME {
|
||||||
// We don't have the right position for ONAME nodes (see #15459 and
|
// 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
|
// others). Using ncase.Pos for now as it will provide the correct
|
||||||
// line number (assuming the expression follows the "case" keyword
|
// line number (assuming the expression follows the "case" keyword
|
||||||
// on the same line). This matches the approach before 1.10.
|
// 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")
|
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
|
// remove implicit conversions; the eventual assignment
|
||||||
// will reintroduce them.
|
// will reintroduce them.
|
||||||
case ir.OAS:
|
case ir.OAS:
|
||||||
if (n.Right.Op == ir.OCONVNOP || n.Right.Op == ir.OCONVIFACE) && n.Right.Implicit() {
|
if (n.Right().Op() == ir.OCONVNOP || n.Right().Op() == ir.OCONVIFACE) && n.Right().Implicit() {
|
||||||
n.Right = n.Right.Left
|
n.SetRight(n.Right().Left())
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Right.Op != ir.ORECV {
|
if n.Right().Op() != ir.ORECV {
|
||||||
base.ErrorfAt(n.Pos, "select assignment must have receive on right hand side")
|
base.ErrorfAt(n.Pos(), "select assignment must have receive on right hand side")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Op = ir.OSELRECV
|
n.SetOp(ir.OSELRECV)
|
||||||
|
|
||||||
// convert x, ok = <-c into OSELRECV2(x, <-c) with ntest=ok
|
// convert x, ok = <-c into OSELRECV2(x, <-c) with ntest=ok
|
||||||
case ir.OAS2RECV:
|
case ir.OAS2RECV:
|
||||||
if n.Right.Op != ir.ORECV {
|
if n.Right().Op() != ir.ORECV {
|
||||||
base.ErrorfAt(n.Pos, "select assignment must have receive on right hand side")
|
base.ErrorfAt(n.Pos(), "select assignment must have receive on right hand side")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Op = ir.OSELRECV2
|
n.SetOp(ir.OSELRECV2)
|
||||||
n.Left = n.List.First()
|
n.SetLeft(n.List().First())
|
||||||
n.List.Set1(n.List.Second())
|
n.PtrList().Set1(n.List().Second())
|
||||||
|
|
||||||
// convert <-c into OSELRECV(N, <-c)
|
// convert <-c into OSELRECV(N, <-c)
|
||||||
case ir.ORECV:
|
case ir.ORECV:
|
||||||
n = ir.NodAt(n.Pos, ir.OSELRECV, nil, n)
|
n = ir.NodAt(n.Pos(), ir.OSELRECV, nil, n)
|
||||||
|
|
||||||
n.SetTypecheck(1)
|
n.SetTypecheck(1)
|
||||||
ncase.Left = n
|
ncase.SetLeft(n)
|
||||||
|
|
||||||
case ir.OSEND:
|
case ir.OSEND:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typecheckslice(ncase.Nbody.Slice(), ctxStmt)
|
typecheckslice(ncase.Body().Slice(), ctxStmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Pos = lno
|
base.Pos = lno
|
||||||
|
|
@ -93,18 +93,18 @@ func typecheckselect(sel *ir.Node) {
|
||||||
|
|
||||||
func walkselect(sel *ir.Node) {
|
func walkselect(sel *ir.Node) {
|
||||||
lno := setlineno(sel)
|
lno := setlineno(sel)
|
||||||
if sel.Nbody.Len() != 0 {
|
if sel.Body().Len() != 0 {
|
||||||
base.Fatalf("double walkselect")
|
base.Fatalf("double walkselect")
|
||||||
}
|
}
|
||||||
|
|
||||||
init := sel.Ninit.Slice()
|
init := sel.Init().Slice()
|
||||||
sel.Ninit.Set(nil)
|
sel.PtrInit().Set(nil)
|
||||||
|
|
||||||
init = append(init, walkselectcases(&sel.List)...)
|
init = append(init, walkselectcases(sel.PtrList())...)
|
||||||
sel.List.Set(nil)
|
sel.PtrList().Set(nil)
|
||||||
|
|
||||||
sel.Nbody.Set(init)
|
sel.PtrBody().Set(init)
|
||||||
walkstmtlist(sel.Nbody.Slice())
|
walkstmtlist(sel.Body().Slice())
|
||||||
|
|
||||||
base.Pos = lno
|
base.Pos = lno
|
||||||
}
|
}
|
||||||
|
|
@ -122,38 +122,38 @@ func walkselectcases(cases *ir.Nodes) []*ir.Node {
|
||||||
if ncas == 1 {
|
if ncas == 1 {
|
||||||
cas := cases.First()
|
cas := cases.First()
|
||||||
setlineno(cas)
|
setlineno(cas)
|
||||||
l := cas.Ninit.Slice()
|
l := cas.Init().Slice()
|
||||||
if cas.Left != nil { // not default:
|
if cas.Left() != nil { // not default:
|
||||||
n := cas.Left
|
n := cas.Left()
|
||||||
l = append(l, n.Ninit.Slice()...)
|
l = append(l, n.Init().Slice()...)
|
||||||
n.Ninit.Set(nil)
|
n.PtrInit().Set(nil)
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
default:
|
default:
|
||||||
base.Fatalf("select %v", n.Op)
|
base.Fatalf("select %v", n.Op())
|
||||||
|
|
||||||
case ir.OSEND:
|
case ir.OSEND:
|
||||||
// already ok
|
// already ok
|
||||||
|
|
||||||
case ir.OSELRECV, ir.OSELRECV2:
|
case ir.OSELRECV, ir.OSELRECV2:
|
||||||
if n.Op == ir.OSELRECV || n.List.Len() == 0 {
|
if n.Op() == ir.OSELRECV || n.List().Len() == 0 {
|
||||||
if n.Left == nil {
|
if n.Left() == nil {
|
||||||
n = n.Right
|
n = n.Right()
|
||||||
} else {
|
} else {
|
||||||
n.Op = ir.OAS
|
n.SetOp(ir.OAS)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Left == nil {
|
if n.Left() == nil {
|
||||||
ir.BlankNode = typecheck(ir.BlankNode, ctxExpr|ctxAssign)
|
ir.BlankNode = typecheck(ir.BlankNode, ctxExpr|ctxAssign)
|
||||||
n.Left = ir.BlankNode
|
n.SetLeft(ir.BlankNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Op = ir.OAS2
|
n.SetOp(ir.OAS2)
|
||||||
n.List.Prepend(n.Left)
|
n.PtrList().Prepend(n.Left())
|
||||||
n.Rlist.Set1(n.Right)
|
n.PtrRlist().Set1(n.Right())
|
||||||
n.Right = nil
|
n.SetRight(nil)
|
||||||
n.Left = nil
|
n.SetLeft(nil)
|
||||||
n.SetTypecheck(0)
|
n.SetTypecheck(0)
|
||||||
n = typecheck(n, ctxStmt)
|
n = typecheck(n, ctxStmt)
|
||||||
}
|
}
|
||||||
|
|
@ -161,7 +161,7 @@ func walkselectcases(cases *ir.Nodes) []*ir.Node {
|
||||||
l = append(l, n)
|
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))
|
l = append(l, ir.Nod(ir.OBREAK, nil, nil))
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
@ -171,24 +171,24 @@ func walkselectcases(cases *ir.Nodes) []*ir.Node {
|
||||||
var dflt *ir.Node
|
var dflt *ir.Node
|
||||||
for _, cas := range cases.Slice() {
|
for _, cas := range cases.Slice() {
|
||||||
setlineno(cas)
|
setlineno(cas)
|
||||||
n := cas.Left
|
n := cas.Left()
|
||||||
if n == nil {
|
if n == nil {
|
||||||
dflt = cas
|
dflt = cas
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.OSEND:
|
case ir.OSEND:
|
||||||
n.Right = ir.Nod(ir.OADDR, n.Right, nil)
|
n.SetRight(ir.Nod(ir.OADDR, n.Right(), nil))
|
||||||
n.Right = typecheck(n.Right, ctxExpr)
|
n.SetRight(typecheck(n.Right(), ctxExpr))
|
||||||
|
|
||||||
case ir.OSELRECV, ir.OSELRECV2:
|
case ir.OSELRECV, ir.OSELRECV2:
|
||||||
if n.Op == ir.OSELRECV2 && n.List.Len() == 0 {
|
if n.Op() == ir.OSELRECV2 && n.List().Len() == 0 {
|
||||||
n.Op = ir.OSELRECV
|
n.SetOp(ir.OSELRECV)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
n.Left = ir.Nod(ir.OADDR, n.Left, nil)
|
n.SetLeft(ir.Nod(ir.OADDR, n.Left(), nil))
|
||||||
n.Left = typecheck(n.Left, ctxExpr)
|
n.SetLeft(typecheck(n.Left(), ctxExpr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -200,43 +200,43 @@ func walkselectcases(cases *ir.Nodes) []*ir.Node {
|
||||||
cas = cases.Second()
|
cas = cases.Second()
|
||||||
}
|
}
|
||||||
|
|
||||||
n := cas.Left
|
n := cas.Left()
|
||||||
setlineno(n)
|
setlineno(n)
|
||||||
r := ir.Nod(ir.OIF, nil, nil)
|
r := ir.Nod(ir.OIF, nil, nil)
|
||||||
r.Ninit.Set(cas.Ninit.Slice())
|
r.PtrInit().Set(cas.Init().Slice())
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
default:
|
default:
|
||||||
base.Fatalf("select %v", n.Op)
|
base.Fatalf("select %v", n.Op())
|
||||||
|
|
||||||
case ir.OSEND:
|
case ir.OSEND:
|
||||||
// if selectnbsend(c, v) { body } else { default body }
|
// if selectnbsend(c, v) { body } else { default body }
|
||||||
ch := n.Left
|
ch := n.Left()
|
||||||
r.Left = mkcall1(chanfn("selectnbsend", 2, ch.Type), types.Types[types.TBOOL], &r.Ninit, ch, n.Right)
|
r.SetLeft(mkcall1(chanfn("selectnbsend", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), ch, n.Right()))
|
||||||
|
|
||||||
case ir.OSELRECV:
|
case ir.OSELRECV:
|
||||||
// if selectnbrecv(&v, c) { body } else { default body }
|
// if selectnbrecv(&v, c) { body } else { default body }
|
||||||
ch := n.Right.Left
|
ch := n.Right().Left()
|
||||||
elem := n.Left
|
elem := n.Left()
|
||||||
if elem == nil {
|
if elem == nil {
|
||||||
elem = nodnil()
|
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:
|
case ir.OSELRECV2:
|
||||||
// if selectnbrecv2(&v, &received, c) { body } else { default body }
|
// if selectnbrecv2(&v, &received, c) { body } else { default body }
|
||||||
ch := n.Right.Left
|
ch := n.Right().Left()
|
||||||
elem := n.Left
|
elem := n.Left()
|
||||||
if elem == nil {
|
if elem == nil {
|
||||||
elem = nodnil()
|
elem = nodnil()
|
||||||
}
|
}
|
||||||
receivedp := ir.Nod(ir.OADDR, n.List.First(), nil)
|
receivedp := ir.Nod(ir.OADDR, n.List().First(), nil)
|
||||||
receivedp = typecheck(receivedp, ctxExpr)
|
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.SetLeft(typecheck(r.Left(), ctxExpr))
|
||||||
r.Nbody.Set(cas.Nbody.Slice())
|
r.PtrBody().Set(cas.Body().Slice())
|
||||||
r.Rlist.Set(append(dflt.Ninit.Slice(), dflt.Nbody.Slice()...))
|
r.PtrRlist().Set(append(dflt.Init().Slice(), dflt.Body().Slice()...))
|
||||||
return []*ir.Node{r, ir.Nod(ir.OBREAK, nil, nil)}
|
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() {
|
for _, cas := range cases.Slice() {
|
||||||
setlineno(cas)
|
setlineno(cas)
|
||||||
|
|
||||||
init = append(init, cas.Ninit.Slice()...)
|
init = append(init, cas.Init().Slice()...)
|
||||||
cas.Ninit.Set(nil)
|
cas.PtrInit().Set(nil)
|
||||||
|
|
||||||
n := cas.Left
|
n := cas.Left()
|
||||||
if n == nil { // default:
|
if n == nil { // default:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var i int
|
var i int
|
||||||
var c, elem *ir.Node
|
var c, elem *ir.Node
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
default:
|
default:
|
||||||
base.Fatalf("select %v", n.Op)
|
base.Fatalf("select %v", n.Op())
|
||||||
case ir.OSEND:
|
case ir.OSEND:
|
||||||
i = nsends
|
i = nsends
|
||||||
nsends++
|
nsends++
|
||||||
c = n.Left
|
c = n.Left()
|
||||||
elem = n.Right
|
elem = n.Right()
|
||||||
case ir.OSELRECV, ir.OSELRECV2:
|
case ir.OSELRECV, ir.OSELRECV2:
|
||||||
nrecvs++
|
nrecvs++
|
||||||
i = ncas - nrecvs
|
i = ncas - nrecvs
|
||||||
c = n.Right.Left
|
c = n.Right().Left()
|
||||||
elem = n.Left
|
elem = n.Left()
|
||||||
}
|
}
|
||||||
|
|
||||||
casorder[i] = cas
|
casorder[i] = cas
|
||||||
|
|
@ -326,9 +326,9 @@ func walkselectcases(cases *ir.Nodes) []*ir.Node {
|
||||||
chosen := temp(types.Types[types.TINT])
|
chosen := temp(types.Types[types.TINT])
|
||||||
recvOK := temp(types.Types[types.TBOOL])
|
recvOK := temp(types.Types[types.TBOOL])
|
||||||
r = ir.Nod(ir.OAS2, nil, nil)
|
r = ir.Nod(ir.OAS2, nil, nil)
|
||||||
r.List.Set2(chosen, recvOK)
|
r.PtrList().Set2(chosen, recvOK)
|
||||||
fn := syslook("selectgo")
|
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)
|
r = typecheck(r, ctxStmt)
|
||||||
init = append(init, r)
|
init = append(init, r)
|
||||||
|
|
||||||
|
|
@ -346,14 +346,14 @@ func walkselectcases(cases *ir.Nodes) []*ir.Node {
|
||||||
|
|
||||||
r := ir.Nod(ir.OIF, cond, nil)
|
r := ir.Nod(ir.OIF, cond, nil)
|
||||||
|
|
||||||
if n := cas.Left; n != nil && n.Op == ir.OSELRECV2 {
|
if n := cas.Left(); n != nil && n.Op() == ir.OSELRECV2 {
|
||||||
x := ir.Nod(ir.OAS, n.List.First(), recvOK)
|
x := ir.Nod(ir.OAS, n.List().First(), recvOK)
|
||||||
x = typecheck(x, ctxStmt)
|
x = typecheck(x, ctxStmt)
|
||||||
r.Nbody.Append(x)
|
r.PtrBody().Append(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Nbody.AppendNodes(&cas.Nbody)
|
r.PtrBody().AppendNodes(cas.PtrBody())
|
||||||
r.Nbody.Append(ir.Nod(ir.OBREAK, nil, nil))
|
r.PtrBody().Append(ir.Nod(ir.OBREAK, nil, nil))
|
||||||
init = append(init, r)
|
init = append(init, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,54 +57,54 @@ func (s *InitSchedule) tryStaticInit(n *ir.Node) bool {
|
||||||
// replaced by multiple simple OAS assignments, and the other
|
// replaced by multiple simple OAS assignments, and the other
|
||||||
// OAS2* assignments mostly necessitate dynamic execution
|
// OAS2* assignments mostly necessitate dynamic execution
|
||||||
// anyway.
|
// anyway.
|
||||||
if n.Op != ir.OAS {
|
if n.Op() != ir.OAS {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if ir.IsBlank(n.Left) && candiscard(n.Right) {
|
if ir.IsBlank(n.Left()) && candiscard(n.Right()) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
lno := setlineno(n)
|
lno := setlineno(n)
|
||||||
defer func() { base.Pos = lno }()
|
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
|
// like staticassign but we are copying an already
|
||||||
// initialized value r.
|
// initialized value r.
|
||||||
func (s *InitSchedule) staticcopy(l *ir.Node, r *ir.Node) bool {
|
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
|
return false
|
||||||
}
|
}
|
||||||
if r.Class() == ir.PFUNC {
|
if r.Class() == ir.PFUNC {
|
||||||
pfuncsym(l, r)
|
pfuncsym(l, r)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if r.Class() != ir.PEXTERN || r.Sym.Pkg != ir.LocalPkg {
|
if r.Class() != ir.PEXTERN || r.Sym().Pkg != ir.LocalPkg {
|
||||||
return false
|
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
|
return false
|
||||||
}
|
}
|
||||||
if r.Name.Defn.Op != ir.OAS {
|
if r.Name().Defn.Op() != ir.OAS {
|
||||||
return false
|
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
|
return false
|
||||||
}
|
}
|
||||||
orig := r
|
orig := r
|
||||||
r = r.Name.Defn.Right
|
r = r.Name().Defn.Right()
|
||||||
|
|
||||||
for r.Op == ir.OCONVNOP && !types.Identical(r.Type, l.Type) {
|
for r.Op() == ir.OCONVNOP && !types.Identical(r.Type(), l.Type()) {
|
||||||
r = r.Left
|
r = r.Left()
|
||||||
}
|
}
|
||||||
|
|
||||||
switch r.Op {
|
switch r.Op() {
|
||||||
case ir.ONAME, ir.OMETHEXPR:
|
case ir.ONAME, ir.OMETHEXPR:
|
||||||
if s.staticcopy(l, r) {
|
if s.staticcopy(l, r) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// We may have skipped past one or more OCONVNOPs, so
|
// We may have skipped past one or more OCONVNOPs, so
|
||||||
// use conv to ensure r is assignable to l (#13263).
|
// 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
|
return true
|
||||||
|
|
||||||
case ir.ONIL:
|
case ir.ONIL:
|
||||||
|
|
@ -114,17 +114,17 @@ func (s *InitSchedule) staticcopy(l *ir.Node, r *ir.Node) bool {
|
||||||
if isZero(r) {
|
if isZero(r) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
litsym(l, r, int(l.Type.Width))
|
litsym(l, r, int(l.Type().Width))
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case ir.OADDR:
|
case ir.OADDR:
|
||||||
if a := r.Left; a.Op == ir.ONAME {
|
if a := r.Left(); a.Op() == ir.ONAME {
|
||||||
addrsym(l, a)
|
addrsym(l, a)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OPTRLIT:
|
case ir.OPTRLIT:
|
||||||
switch r.Left.Op {
|
switch r.Left().Op() {
|
||||||
case ir.OARRAYLIT, ir.OSLICELIT, ir.OSTRUCTLIT, ir.OMAPLIT:
|
case ir.OARRAYLIT, ir.OSLICELIT, ir.OSTRUCTLIT, ir.OMAPLIT:
|
||||||
// copy pointer
|
// copy pointer
|
||||||
addrsym(l, s.inittemps[r])
|
addrsym(l, s.inittemps[r])
|
||||||
|
|
@ -134,7 +134,7 @@ func (s *InitSchedule) staticcopy(l *ir.Node, r *ir.Node) bool {
|
||||||
case ir.OSLICELIT:
|
case ir.OSLICELIT:
|
||||||
// copy slice
|
// copy slice
|
||||||
a := s.inittemps[r]
|
a := s.inittemps[r]
|
||||||
slicesym(l, a, r.Right.Int64Val())
|
slicesym(l, a, r.Right().Int64Val())
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case ir.OARRAYLIT, ir.OSTRUCTLIT:
|
case ir.OARRAYLIT, ir.OSTRUCTLIT:
|
||||||
|
|
@ -143,10 +143,10 @@ func (s *InitSchedule) staticcopy(l *ir.Node, r *ir.Node) bool {
|
||||||
n := ir.Copy(l)
|
n := ir.Copy(l)
|
||||||
for i := range p.E {
|
for i := range p.E {
|
||||||
e := &p.E[i]
|
e := &p.E[i]
|
||||||
n.Xoffset = l.Xoffset + e.Xoffset
|
n.SetOffset(l.Offset() + e.Xoffset)
|
||||||
n.Type = e.Expr.Type
|
n.SetType(e.Expr.Type())
|
||||||
if e.Expr.Op == ir.OLITERAL || e.Expr.Op == ir.ONIL {
|
if e.Expr.Op() == ir.OLITERAL || e.Expr.Op() == ir.ONIL {
|
||||||
litsym(n, e.Expr, int(n.Type.Width))
|
litsym(n, e.Expr, int(n.Type().Width))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ll := ir.SepCopy(n)
|
ll := ir.SepCopy(n)
|
||||||
|
|
@ -156,8 +156,8 @@ func (s *InitSchedule) staticcopy(l *ir.Node, r *ir.Node) bool {
|
||||||
// Requires computation, but we're
|
// Requires computation, but we're
|
||||||
// copying someone else's computation.
|
// copying someone else's computation.
|
||||||
rr := ir.SepCopy(orig)
|
rr := ir.SepCopy(orig)
|
||||||
rr.Type = ll.Type
|
rr.SetType(ll.Type())
|
||||||
rr.Xoffset = rr.Xoffset + e.Xoffset
|
rr.SetOffset(rr.Offset() + e.Xoffset)
|
||||||
setlineno(rr)
|
setlineno(rr)
|
||||||
s.append(ir.Nod(ir.OAS, ll, 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 {
|
func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool {
|
||||||
for r.Op == ir.OCONVNOP {
|
for r.Op() == ir.OCONVNOP {
|
||||||
r = r.Left
|
r = r.Left()
|
||||||
}
|
}
|
||||||
|
|
||||||
switch r.Op {
|
switch r.Op() {
|
||||||
case ir.ONAME, ir.OMETHEXPR:
|
case ir.ONAME, ir.OMETHEXPR:
|
||||||
return s.staticcopy(l, r)
|
return s.staticcopy(l, r)
|
||||||
|
|
||||||
|
|
@ -184,36 +184,36 @@ func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool {
|
||||||
if isZero(r) {
|
if isZero(r) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
litsym(l, r, int(l.Type.Width))
|
litsym(l, r, int(l.Type().Width))
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case ir.OADDR:
|
case ir.OADDR:
|
||||||
if nam := stataddr(r.Left); nam != nil {
|
if nam := stataddr(r.Left()); nam != nil {
|
||||||
addrsym(l, nam)
|
addrsym(l, nam)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
case ir.OPTRLIT:
|
case ir.OPTRLIT:
|
||||||
switch r.Left.Op {
|
switch r.Left().Op() {
|
||||||
case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT, ir.OSTRUCTLIT:
|
case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT, ir.OSTRUCTLIT:
|
||||||
// Init pointer.
|
// Init pointer.
|
||||||
a := staticname(r.Left.Type)
|
a := staticname(r.Left().Type())
|
||||||
|
|
||||||
s.inittemps[r] = a
|
s.inittemps[r] = a
|
||||||
addrsym(l, a)
|
addrsym(l, a)
|
||||||
|
|
||||||
// Init underlying literal.
|
// Init underlying literal.
|
||||||
if !s.staticassign(a, r.Left) {
|
if !s.staticassign(a, r.Left()) {
|
||||||
s.append(ir.Nod(ir.OAS, a, r.Left))
|
s.append(ir.Nod(ir.OAS, a, r.Left()))
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
//dump("not static ptrlit", r);
|
//dump("not static ptrlit", r);
|
||||||
|
|
||||||
case ir.OSTR2BYTES:
|
case ir.OSTR2BYTES:
|
||||||
if l.Class() == ir.PEXTERN && r.Left.Op == ir.OLITERAL {
|
if l.Class() == ir.PEXTERN && r.Left().Op() == ir.OLITERAL {
|
||||||
sval := r.Left.StringVal()
|
sval := r.Left().StringVal()
|
||||||
slicebytes(l, sval)
|
slicebytes(l, sval)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -221,8 +221,8 @@ func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool {
|
||||||
case ir.OSLICELIT:
|
case ir.OSLICELIT:
|
||||||
s.initplan(r)
|
s.initplan(r)
|
||||||
// Init slice.
|
// Init slice.
|
||||||
bound := r.Right.Int64Val()
|
bound := r.Right().Int64Val()
|
||||||
ta := types.NewArray(r.Type.Elem(), bound)
|
ta := types.NewArray(r.Type().Elem(), bound)
|
||||||
ta.SetNoalg(true)
|
ta.SetNoalg(true)
|
||||||
a := staticname(ta)
|
a := staticname(ta)
|
||||||
s.inittemps[r] = a
|
s.inittemps[r] = a
|
||||||
|
|
@ -238,10 +238,10 @@ func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool {
|
||||||
n := ir.Copy(l)
|
n := ir.Copy(l)
|
||||||
for i := range p.E {
|
for i := range p.E {
|
||||||
e := &p.E[i]
|
e := &p.E[i]
|
||||||
n.Xoffset = l.Xoffset + e.Xoffset
|
n.SetOffset(l.Offset() + e.Xoffset)
|
||||||
n.Type = e.Expr.Type
|
n.SetType(e.Expr.Type())
|
||||||
if e.Expr.Op == ir.OLITERAL || e.Expr.Op == ir.ONIL {
|
if e.Expr.Op() == ir.OLITERAL || e.Expr.Op() == ir.ONIL {
|
||||||
litsym(n, e.Expr, int(n.Type.Width))
|
litsym(n, e.Expr, int(n.Type().Width))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
setlineno(e.Expr)
|
setlineno(e.Expr)
|
||||||
|
|
@ -259,11 +259,11 @@ func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool {
|
||||||
case ir.OCLOSURE:
|
case ir.OCLOSURE:
|
||||||
if hasemptycvars(r) {
|
if hasemptycvars(r) {
|
||||||
if base.Debug.Closure > 0 {
|
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,
|
// Closures with no captured variables are globals,
|
||||||
// so the assignment can be done at link time.
|
// so the assignment can be done at link time.
|
||||||
pfuncsym(l, r.Func.Nname)
|
pfuncsym(l, r.Func().Nname)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
closuredebugruntimecheck(r)
|
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.
|
// Determine the underlying concrete type and value we are converting from.
|
||||||
val := r
|
val := r
|
||||||
for val.Op == ir.OCONVIFACE {
|
for val.Op() == ir.OCONVIFACE {
|
||||||
val = val.Left
|
val = val.Left()
|
||||||
}
|
}
|
||||||
|
|
||||||
if val.Type.IsInterface() {
|
if val.Type().IsInterface() {
|
||||||
// val is an interface type.
|
// val is an interface type.
|
||||||
// If val is nil, we can statically initialize l;
|
// If val is nil, we can statically initialize l;
|
||||||
// both words are zero and so there no work to do, so report success.
|
// 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,
|
// 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.
|
// 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
|
var itab *ir.Node
|
||||||
if l.Type.IsEmptyInterface() {
|
if l.Type().IsEmptyInterface() {
|
||||||
itab = typename(val.Type)
|
itab = typename(val.Type())
|
||||||
} else {
|
} else {
|
||||||
itab = itabname(val.Type, l.Type)
|
itab = itabname(val.Type(), l.Type())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a copy of l to modify while we emit data.
|
// Create a copy of l to modify while we emit data.
|
||||||
n := ir.Copy(l)
|
n := ir.Copy(l)
|
||||||
|
|
||||||
// Emit itab, advance offset.
|
// Emit itab, advance offset.
|
||||||
addrsym(n, itab.Left) // itab is an OADDR node
|
addrsym(n, itab.Left()) // itab is an OADDR node
|
||||||
n.Xoffset = n.Xoffset + int64(Widthptr)
|
n.SetOffset(n.Offset() + int64(Widthptr))
|
||||||
|
|
||||||
// Emit data.
|
// Emit data.
|
||||||
if isdirectiface(val.Type) {
|
if isdirectiface(val.Type()) {
|
||||||
if val.Op == ir.ONIL {
|
if val.Op() == ir.ONIL {
|
||||||
// Nil is zero, nothing to do.
|
// Nil is zero, nothing to do.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// Copy val directly into n.
|
// Copy val directly into n.
|
||||||
n.Type = val.Type
|
n.SetType(val.Type())
|
||||||
setlineno(val)
|
setlineno(val)
|
||||||
a := ir.SepCopy(n)
|
a := ir.SepCopy(n)
|
||||||
if !s.staticassign(a, val) {
|
if !s.staticassign(a, val) {
|
||||||
|
|
@ -318,7 +318,7 @@ func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Construct temp to hold val, write pointer to temp into n.
|
// Construct temp to hold val, write pointer to temp into n.
|
||||||
a := staticname(val.Type)
|
a := staticname(val.Type())
|
||||||
s.inittemps[val] = a
|
s.inittemps[val] = a
|
||||||
if !s.staticassign(a, val) {
|
if !s.staticassign(a, val) {
|
||||||
s.append(ir.Nod(ir.OAS, 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)))
|
n := NewName(lookup(fmt.Sprintf("%s%d", obj.StaticNamePref, statuniqgen)))
|
||||||
statuniqgen++
|
statuniqgen++
|
||||||
addvar(n, t, ir.PEXTERN)
|
addvar(n, t, ir.PEXTERN)
|
||||||
n.Sym.Linksym().Set(obj.AttrLocal, true)
|
n.Sym().Linksym().Set(obj.AttrLocal, true)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -380,12 +380,12 @@ func staticname(t *types.Type) *ir.Node {
|
||||||
func readonlystaticname(t *types.Type) *ir.Node {
|
func readonlystaticname(t *types.Type) *ir.Node {
|
||||||
n := staticname(t)
|
n := staticname(t)
|
||||||
n.MarkReadonly()
|
n.MarkReadonly()
|
||||||
n.Sym.Linksym().Set(obj.AttrContentAddressable, true)
|
n.Sym().Linksym().Set(obj.AttrContentAddressable, true)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSimpleName(n *ir.Node) bool {
|
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) {
|
func litas(l *ir.Node, r *ir.Node, init *ir.Nodes) {
|
||||||
|
|
@ -406,7 +406,7 @@ const (
|
||||||
// getdyn calculates the initGenType for n.
|
// getdyn calculates the initGenType for n.
|
||||||
// If top is false, getdyn is recursing.
|
// If top is false, getdyn is recursing.
|
||||||
func getdyn(n *ir.Node, top bool) initGenType {
|
func getdyn(n *ir.Node, top bool) initGenType {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
default:
|
default:
|
||||||
if isGoConst(n) {
|
if isGoConst(n) {
|
||||||
return initConst
|
return initConst
|
||||||
|
|
@ -417,7 +417,7 @@ func getdyn(n *ir.Node, top bool) initGenType {
|
||||||
if !top {
|
if !top {
|
||||||
return initDynamic
|
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.
|
// <25% of entries have explicit values.
|
||||||
// Very rough estimation, it takes 4 bytes of instructions
|
// Very rough estimation, it takes 4 bytes of instructions
|
||||||
// to initialize 1 byte of result. So don't use a static
|
// 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
|
var mode initGenType
|
||||||
for _, n1 := range n.List.Slice() {
|
for _, n1 := range n.List().Slice() {
|
||||||
switch n1.Op {
|
switch n1.Op() {
|
||||||
case ir.OKEY:
|
case ir.OKEY:
|
||||||
n1 = n1.Right
|
n1 = n1.Right()
|
||||||
case ir.OSTRUCTKEY:
|
case ir.OSTRUCTKEY:
|
||||||
n1 = n1.Left
|
n1 = n1.Left()
|
||||||
}
|
}
|
||||||
mode |= getdyn(n1, false)
|
mode |= getdyn(n1, false)
|
||||||
if mode == initDynamic|initConst {
|
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.
|
// isStaticCompositeLiteral reports whether n is a compile-time constant.
|
||||||
func isStaticCompositeLiteral(n *ir.Node) bool {
|
func isStaticCompositeLiteral(n *ir.Node) bool {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.OSLICELIT:
|
case ir.OSLICELIT:
|
||||||
return false
|
return false
|
||||||
case ir.OARRAYLIT:
|
case ir.OARRAYLIT:
|
||||||
for _, r := range n.List.Slice() {
|
for _, r := range n.List().Slice() {
|
||||||
if r.Op == ir.OKEY {
|
if r.Op() == ir.OKEY {
|
||||||
r = r.Right
|
r = r.Right()
|
||||||
}
|
}
|
||||||
if !isStaticCompositeLiteral(r) {
|
if !isStaticCompositeLiteral(r) {
|
||||||
return false
|
return false
|
||||||
|
|
@ -462,11 +462,11 @@ func isStaticCompositeLiteral(n *ir.Node) bool {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
case ir.OSTRUCTLIT:
|
case ir.OSTRUCTLIT:
|
||||||
for _, r := range n.List.Slice() {
|
for _, r := range n.List().Slice() {
|
||||||
if r.Op != ir.OSTRUCTKEY {
|
if r.Op() != ir.OSTRUCTKEY {
|
||||||
base.Fatalf("isStaticCompositeLiteral: rhs not OSTRUCTKEY: %v", r)
|
base.Fatalf("isStaticCompositeLiteral: rhs not OSTRUCTKEY: %v", r)
|
||||||
}
|
}
|
||||||
if !isStaticCompositeLiteral(r.Left) {
|
if !isStaticCompositeLiteral(r.Left()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -476,13 +476,13 @@ func isStaticCompositeLiteral(n *ir.Node) bool {
|
||||||
case ir.OCONVIFACE:
|
case ir.OCONVIFACE:
|
||||||
// See staticassign's OCONVIFACE case for comments.
|
// See staticassign's OCONVIFACE case for comments.
|
||||||
val := n
|
val := n
|
||||||
for val.Op == ir.OCONVIFACE {
|
for val.Op() == ir.OCONVIFACE {
|
||||||
val = val.Left
|
val = val.Left()
|
||||||
}
|
}
|
||||||
if val.Type.IsInterface() {
|
if val.Type().IsInterface() {
|
||||||
return val.Op == ir.ONIL
|
return val.Op() == ir.ONIL
|
||||||
}
|
}
|
||||||
if isdirectiface(val.Type) && val.Op == ir.ONIL {
|
if isdirectiface(val.Type()) && val.Op() == ir.ONIL {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return isStaticCompositeLiteral(val)
|
return isStaticCompositeLiteral(val)
|
||||||
|
|
@ -512,16 +512,16 @@ const (
|
||||||
func fixedlit(ctxt initContext, kind initKind, n *ir.Node, var_ *ir.Node, init *ir.Nodes) {
|
func fixedlit(ctxt initContext, kind initKind, n *ir.Node, var_ *ir.Node, init *ir.Nodes) {
|
||||||
isBlank := var_ == ir.BlankNode
|
isBlank := var_ == ir.BlankNode
|
||||||
var splitnode func(*ir.Node) (a *ir.Node, value *ir.Node)
|
var splitnode func(*ir.Node) (a *ir.Node, value *ir.Node)
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.OARRAYLIT, ir.OSLICELIT:
|
case ir.OARRAYLIT, ir.OSLICELIT:
|
||||||
var k int64
|
var k int64
|
||||||
splitnode = func(r *ir.Node) (*ir.Node, *ir.Node) {
|
splitnode = func(r *ir.Node) (*ir.Node, *ir.Node) {
|
||||||
if r.Op == ir.OKEY {
|
if r.Op() == ir.OKEY {
|
||||||
k = indexconst(r.Left)
|
k = indexconst(r.Left())
|
||||||
if k < 0 {
|
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))
|
a := ir.Nod(ir.OINDEX, var_, nodintconst(k))
|
||||||
k++
|
k++
|
||||||
|
|
@ -532,26 +532,26 @@ func fixedlit(ctxt initContext, kind initKind, n *ir.Node, var_ *ir.Node, init *
|
||||||
}
|
}
|
||||||
case ir.OSTRUCTLIT:
|
case ir.OSTRUCTLIT:
|
||||||
splitnode = func(r *ir.Node) (*ir.Node, *ir.Node) {
|
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)
|
base.Fatalf("fixedlit: rhs not OSTRUCTKEY: %v", r)
|
||||||
}
|
}
|
||||||
if r.Sym.IsBlank() || isBlank {
|
if r.Sym().IsBlank() || isBlank {
|
||||||
return ir.BlankNode, r.Left
|
return ir.BlankNode, r.Left()
|
||||||
}
|
}
|
||||||
setlineno(r)
|
setlineno(r)
|
||||||
return nodSym(ir.ODOT, var_, r.Sym), r.Left
|
return nodSym(ir.ODOT, var_, r.Sym()), r.Left()
|
||||||
}
|
}
|
||||||
default:
|
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)
|
a, value := splitnode(r)
|
||||||
if a == ir.BlankNode && candiscard(value) {
|
if a == ir.BlankNode && candiscard(value) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
switch value.Op {
|
switch value.Op() {
|
||||||
case ir.OSLICELIT:
|
case ir.OSLICELIT:
|
||||||
if (kind == initKindStatic && ctxt == inNonInitFunction) || (kind == initKindDynamic && ctxt == inInitFunction) {
|
if (kind == initKindStatic && ctxt == inNonInitFunction) || (kind == initKindDynamic && ctxt == inInitFunction) {
|
||||||
slicelit(ctxt, value, a, init)
|
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 {
|
func isSmallSliceLit(n *ir.Node) bool {
|
||||||
if n.Op != ir.OSLICELIT {
|
if n.Op() != ir.OSLICELIT {
|
||||||
return false
|
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) {
|
func slicelit(ctxt initContext, n *ir.Node, var_ *ir.Node, init *ir.Nodes) {
|
||||||
// make an array type corresponding the number of elements we have
|
// 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)
|
dowidth(t)
|
||||||
|
|
||||||
if ctxt == inNonInitFunction {
|
if ctxt == inNonInitFunction {
|
||||||
|
|
@ -658,7 +658,7 @@ func slicelit(ctxt initContext, n *ir.Node, var_ *ir.Node, init *ir.Nodes) {
|
||||||
var a *ir.Node
|
var a *ir.Node
|
||||||
if x := prealloc[n]; x != nil {
|
if x := prealloc[n]; x != nil {
|
||||||
// temp allocated during order.go for dddarg
|
// 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")
|
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)
|
a = ir.Nod(ir.OADDR, x, nil)
|
||||||
} else if n.Esc == EscNone {
|
} else if n.Esc() == EscNone {
|
||||||
a = temp(t)
|
a = temp(t)
|
||||||
if vstat == nil {
|
if vstat == nil {
|
||||||
a = ir.Nod(ir.OAS, temp(t), nil)
|
a = ir.Nod(ir.OAS, temp(t), nil)
|
||||||
a = typecheck(a, ctxStmt)
|
a = typecheck(a, ctxStmt)
|
||||||
init.Append(a) // zero new temp
|
init.Append(a) // zero new temp
|
||||||
a = a.Left
|
a = a.Left()
|
||||||
} else {
|
} else {
|
||||||
init.Append(ir.Nod(ir.OVARDEF, a, nil))
|
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)
|
a = ir.Nod(ir.OADDR, a, nil)
|
||||||
} else {
|
} else {
|
||||||
a = ir.Nod(ir.ONEW, nil, nil)
|
a = ir.Nod(ir.ONEW, nil, nil)
|
||||||
a.List.Set1(typenod(t))
|
a.PtrList().Set1(typenod(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
a = ir.Nod(ir.OAS, vauto, a)
|
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)
|
// put dynamics into array (5)
|
||||||
var index int64
|
var index int64
|
||||||
for _, value := range n.List.Slice() {
|
for _, value := range n.List().Slice() {
|
||||||
if value.Op == ir.OKEY {
|
if value.Op() == ir.OKEY {
|
||||||
index = indexconst(value.Left)
|
index = indexconst(value.Left())
|
||||||
if index < 0 {
|
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 := ir.Nod(ir.OINDEX, vauto, nodintconst(index))
|
||||||
a.SetBounded(true)
|
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?
|
// TODO need to check bounds?
|
||||||
|
|
||||||
switch value.Op {
|
switch value.Op() {
|
||||||
case ir.OSLICELIT:
|
case ir.OSLICELIT:
|
||||||
break
|
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) {
|
func maplit(n *ir.Node, m *ir.Node, init *ir.Nodes) {
|
||||||
// make the map var
|
// make the map var
|
||||||
a := ir.Nod(ir.OMAKE, nil, nil)
|
a := ir.Nod(ir.OMAKE, nil, nil)
|
||||||
a.Esc = n.Esc
|
a.SetEsc(n.Esc())
|
||||||
a.List.Set2(typenod(n.Type), nodintconst(int64(n.List.Len())))
|
a.PtrList().Set2(typenod(n.Type()), nodintconst(int64(n.List().Len())))
|
||||||
litas(m, a, init)
|
litas(m, a, init)
|
||||||
|
|
||||||
entries := n.List.Slice()
|
entries := n.List().Slice()
|
||||||
|
|
||||||
// The order pass already removed any dynamic (runtime-computed) entries.
|
// The order pass already removed any dynamic (runtime-computed) entries.
|
||||||
// All remaining entries are static. Double-check that.
|
// All remaining entries are static. Double-check that.
|
||||||
for _, r := range entries {
|
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)
|
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.
|
// For a large number of entries, put them in an array and loop.
|
||||||
|
|
||||||
// build types [count]Tindex and [count]Tvalue
|
// build types [count]Tindex and [count]Tvalue
|
||||||
tk := types.NewArray(n.Type.Key(), int64(len(entries)))
|
tk := types.NewArray(n.Type().Key(), int64(len(entries)))
|
||||||
te := types.NewArray(n.Type.Elem(), int64(len(entries)))
|
te := types.NewArray(n.Type().Elem(), int64(len(entries)))
|
||||||
|
|
||||||
tk.SetNoalg(true)
|
tk.SetNoalg(true)
|
||||||
te.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)
|
datak := ir.Nod(ir.OARRAYLIT, nil, nil)
|
||||||
datae := ir.Nod(ir.OARRAYLIT, nil, nil)
|
datae := ir.Nod(ir.OARRAYLIT, nil, nil)
|
||||||
for _, r := range entries {
|
for _, r := range entries {
|
||||||
datak.List.Append(r.Left)
|
datak.PtrList().Append(r.Left())
|
||||||
datae.List.Append(r.Right)
|
datae.PtrList().Append(r.Right())
|
||||||
}
|
}
|
||||||
fixedlit(inInitFunction, initKindStatic, datak, vstatk, init)
|
fixedlit(inInitFunction, initKindStatic, datak, vstatk, init)
|
||||||
fixedlit(inInitFunction, initKindStatic, datae, vstate, 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)
|
body := ir.Nod(ir.OAS, lhs, rhs)
|
||||||
|
|
||||||
loop := ir.Nod(ir.OFOR, cond, incr)
|
loop := ir.Nod(ir.OFOR, cond, incr)
|
||||||
loop.Nbody.Set1(body)
|
loop.PtrBody().Set1(body)
|
||||||
loop.Ninit.Set1(zero)
|
loop.PtrInit().Set1(zero)
|
||||||
|
|
||||||
loop = typecheck(loop, ctxStmt)
|
loop = typecheck(loop, ctxStmt)
|
||||||
loop = walkstmt(loop)
|
loop = walkstmt(loop)
|
||||||
|
|
@ -833,11 +833,11 @@ func maplit(n *ir.Node, m *ir.Node, init *ir.Nodes) {
|
||||||
// Build list of var[c] = expr.
|
// Build list of var[c] = expr.
|
||||||
// Use temporaries so that mapassign1 can have addressable key, elem.
|
// Use temporaries so that mapassign1 can have addressable key, elem.
|
||||||
// TODO(josharian): avoid map key temporaries for mapfast_* assignments with literal keys.
|
// TODO(josharian): avoid map key temporaries for mapfast_* assignments with literal keys.
|
||||||
tmpkey := temp(m.Type.Key())
|
tmpkey := temp(m.Type().Key())
|
||||||
tmpelem := temp(m.Type.Elem())
|
tmpelem := temp(m.Type().Elem())
|
||||||
|
|
||||||
for _, r := range entries {
|
for _, r := range entries {
|
||||||
index, elem := r.Left, r.Right
|
index, elem := r.Left(), r.Right()
|
||||||
|
|
||||||
setlineno(index)
|
setlineno(index)
|
||||||
a := ir.Nod(ir.OAS, tmpkey, 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) {
|
func anylit(n *ir.Node, var_ *ir.Node, init *ir.Nodes) {
|
||||||
t := n.Type
|
t := n.Type()
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
default:
|
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:
|
case ir.ONAME, ir.OMETHEXPR:
|
||||||
a := ir.Nod(ir.OAS, var_, n)
|
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
|
var r *ir.Node
|
||||||
if n.Right != nil {
|
if n.Right() != nil {
|
||||||
// n.Right is stack temporary used as backing store.
|
// 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)
|
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 = ir.Nod(ir.OADDR, n.Right(), nil)
|
||||||
r = typecheck(r, ctxExpr)
|
r = typecheck(r, ctxExpr)
|
||||||
} else {
|
} else {
|
||||||
r = ir.Nod(ir.ONEW, nil, nil)
|
r = ir.Nod(ir.ONEW, nil, nil)
|
||||||
r.SetTypecheck(1)
|
r.SetTypecheck(1)
|
||||||
r.Type = t
|
r.SetType(t)
|
||||||
r.Esc = n.Esc
|
r.SetEsc(n.Esc())
|
||||||
}
|
}
|
||||||
|
|
||||||
r = walkexpr(r, init)
|
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_ = ir.Nod(ir.ODEREF, var_, nil)
|
||||||
var_ = typecheck(var_, ctxExpr|ctxAssign)
|
var_ = typecheck(var_, ctxExpr|ctxAssign)
|
||||||
anylit(n.Left, var_, init)
|
anylit(n.Left(), var_, init)
|
||||||
|
|
||||||
case ir.OSTRUCTLIT, ir.OARRAYLIT:
|
case ir.OSTRUCTLIT, ir.OARRAYLIT:
|
||||||
if !t.IsStruct() && !t.IsArray() {
|
if !t.IsStruct() && !t.IsArray() {
|
||||||
base.Fatalf("anylit: not struct/array")
|
base.Fatalf("anylit: not struct/array")
|
||||||
}
|
}
|
||||||
|
|
||||||
if isSimpleName(var_) && n.List.Len() > 4 {
|
if isSimpleName(var_) && n.List().Len() > 4 {
|
||||||
// lay out static data
|
// lay out static data
|
||||||
vstat := readonlystaticname(t)
|
vstat := readonlystaticname(t)
|
||||||
|
|
||||||
ctxt := inInitFunction
|
ctxt := inInitFunction
|
||||||
if n.Op == ir.OARRAYLIT {
|
if n.Op() == ir.OARRAYLIT {
|
||||||
ctxt = inNonInitFunction
|
ctxt = inNonInitFunction
|
||||||
}
|
}
|
||||||
fixedlit(ctxt, initKindStatic, n, vstat, init)
|
fixedlit(ctxt, initKindStatic, n, vstat, init)
|
||||||
|
|
@ -933,13 +933,13 @@ func anylit(n *ir.Node, var_ *ir.Node, init *ir.Nodes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var components int64
|
var components int64
|
||||||
if n.Op == ir.OARRAYLIT {
|
if n.Op() == ir.OARRAYLIT {
|
||||||
components = t.NumElem()
|
components = t.NumElem()
|
||||||
} else {
|
} else {
|
||||||
components = int64(t.NumFields())
|
components = int64(t.NumFields())
|
||||||
}
|
}
|
||||||
// initialization of an array or struct with unspecified components (missing fields or arrays)
|
// 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 := ir.Nod(ir.OAS, var_, nil)
|
||||||
a = typecheck(a, ctxStmt)
|
a = typecheck(a, ctxStmt)
|
||||||
a = walkexpr(a, init)
|
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 {
|
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
|
// not a special composite literal assignment
|
||||||
return false
|
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
|
// not a special composite literal assignment
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !isSimpleName(n.Left) {
|
if !isSimpleName(n.Left()) {
|
||||||
// not a special composite literal assignment
|
// not a special composite literal assignment
|
||||||
return false
|
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
|
// not a special composite literal assignment
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Right.Op {
|
switch n.Right().Op() {
|
||||||
default:
|
default:
|
||||||
// not a special composite literal assignment
|
// not a special composite literal assignment
|
||||||
return false
|
return false
|
||||||
|
|
||||||
case ir.OSTRUCTLIT, ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
|
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
|
// not a special composite literal assignment
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
anylit(n.Right, n.Left, init)
|
anylit(n.Right(), n.Left(), init)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Op = ir.OEMPTY
|
n.SetOp(ir.OEMPTY)
|
||||||
n.Right = nil
|
n.SetRight(nil)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1008,38 +1008,38 @@ func stataddr(n *ir.Node) *ir.Node {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.ONAME, ir.OMETHEXPR:
|
case ir.ONAME, ir.OMETHEXPR:
|
||||||
return ir.SepCopy(n)
|
return ir.SepCopy(n)
|
||||||
|
|
||||||
case ir.ODOT:
|
case ir.ODOT:
|
||||||
nam := stataddr(n.Left)
|
nam := stataddr(n.Left())
|
||||||
if nam == nil {
|
if nam == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
nam.Xoffset = nam.Xoffset + n.Xoffset
|
nam.SetOffset(nam.Offset() + n.Offset())
|
||||||
nam.Type = n.Type
|
nam.SetType(n.Type())
|
||||||
return nam
|
return nam
|
||||||
|
|
||||||
case ir.OINDEX:
|
case ir.OINDEX:
|
||||||
if n.Left.Type.IsSlice() {
|
if n.Left().Type().IsSlice() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
nam := stataddr(n.Left)
|
nam := stataddr(n.Left())
|
||||||
if nam == nil {
|
if nam == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
l := getlit(n.Right)
|
l := getlit(n.Right())
|
||||||
if l < 0 {
|
if l < 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for overflow.
|
// 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
|
break
|
||||||
}
|
}
|
||||||
nam.Xoffset = nam.Xoffset + int64(l)*n.Type.Width
|
nam.SetOffset(nam.Offset() + int64(l)*n.Type().Width)
|
||||||
nam.Type = n.Type
|
nam.SetType(n.Type())
|
||||||
return nam
|
return nam
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1052,41 +1052,41 @@ func (s *InitSchedule) initplan(n *ir.Node) {
|
||||||
}
|
}
|
||||||
p := new(InitPlan)
|
p := new(InitPlan)
|
||||||
s.initplans[n] = p
|
s.initplans[n] = p
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
default:
|
default:
|
||||||
base.Fatalf("initplan")
|
base.Fatalf("initplan")
|
||||||
|
|
||||||
case ir.OARRAYLIT, ir.OSLICELIT:
|
case ir.OARRAYLIT, ir.OSLICELIT:
|
||||||
var k int64
|
var k int64
|
||||||
for _, a := range n.List.Slice() {
|
for _, a := range n.List().Slice() {
|
||||||
if a.Op == ir.OKEY {
|
if a.Op() == ir.OKEY {
|
||||||
k = indexconst(a.Left)
|
k = indexconst(a.Left())
|
||||||
if k < 0 {
|
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++
|
k++
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OSTRUCTLIT:
|
case ir.OSTRUCTLIT:
|
||||||
for _, a := range n.List.Slice() {
|
for _, a := range n.List().Slice() {
|
||||||
if a.Op != ir.OSTRUCTKEY {
|
if a.Op() != ir.OSTRUCTKEY {
|
||||||
base.Fatalf("initplan structlit")
|
base.Fatalf("initplan structlit")
|
||||||
}
|
}
|
||||||
if a.Sym.IsBlank() {
|
if a.Sym().IsBlank() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
s.addvalue(p, a.Xoffset, a.Left)
|
s.addvalue(p, a.Offset(), a.Left())
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OMAPLIT:
|
case ir.OMAPLIT:
|
||||||
for _, a := range n.List.Slice() {
|
for _, a := range n.List().Slice() {
|
||||||
if a.Op != ir.OKEY {
|
if a.Op() != ir.OKEY {
|
||||||
base.Fatalf("initplan maplit")
|
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 {
|
func isZero(n *ir.Node) bool {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.ONIL:
|
case ir.ONIL:
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
@ -1129,9 +1129,9 @@ func isZero(n *ir.Node) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OARRAYLIT:
|
case ir.OARRAYLIT:
|
||||||
for _, n1 := range n.List.Slice() {
|
for _, n1 := range n.List().Slice() {
|
||||||
if n1.Op == ir.OKEY {
|
if n1.Op() == ir.OKEY {
|
||||||
n1 = n1.Right
|
n1 = n1.Right()
|
||||||
}
|
}
|
||||||
if !isZero(n1) {
|
if !isZero(n1) {
|
||||||
return false
|
return false
|
||||||
|
|
@ -1140,8 +1140,8 @@ func isZero(n *ir.Node) bool {
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case ir.OSTRUCTLIT:
|
case ir.OSTRUCTLIT:
|
||||||
for _, n1 := range n.List.Slice() {
|
for _, n1 := range n.List().Slice() {
|
||||||
if !isZero(n1.Left) {
|
if !isZero(n1.Left()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1152,25 +1152,25 @@ func isZero(n *ir.Node) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func isvaluelit(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) {
|
func genAsStatic(as *ir.Node) {
|
||||||
if as.Left.Type == nil {
|
if as.Left().Type() == nil {
|
||||||
base.Fatalf("genAsStatic as.Left not typechecked")
|
base.Fatalf("genAsStatic as.Left not typechecked")
|
||||||
}
|
}
|
||||||
|
|
||||||
nam := stataddr(as.Left)
|
nam := stataddr(as.Left())
|
||||||
if nam == nil || (nam.Class() != ir.PEXTERN && as.Left != ir.BlankNode) {
|
if nam == nil || (nam.Class() != ir.PEXTERN && as.Left() != ir.BlankNode) {
|
||||||
base.Fatalf("genAsStatic: lhs %v", as.Left)
|
base.Fatalf("genAsStatic: lhs %v", as.Left())
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case as.Right.Op == ir.OLITERAL:
|
case as.Right().Op() == ir.OLITERAL:
|
||||||
litsym(nam, as.Right, int(as.Right.Type.Width))
|
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:
|
case (as.Right().Op() == ir.ONAME || as.Right().Op() == ir.OMETHEXPR) && as.Right().Class() == ir.PFUNC:
|
||||||
pfuncsym(nam, as.Right)
|
pfuncsym(nam, as.Right())
|
||||||
default:
|
default:
|
||||||
base.Fatalf("genAsStatic: rhs %v", as.Right)
|
base.Fatalf("genAsStatic: rhs %v", as.Right())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -41,16 +41,16 @@ var (
|
||||||
// whose Pos will point back to their declaration position rather than
|
// whose Pos will point back to their declaration position rather than
|
||||||
// their usage position.
|
// their usage position.
|
||||||
func hasUniquePos(n *ir.Node) bool {
|
func hasUniquePos(n *ir.Node) bool {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.ONAME, ir.OPACK:
|
case ir.ONAME, ir.OPACK:
|
||||||
return false
|
return false
|
||||||
case ir.OLITERAL, ir.ONIL, ir.OTYPE:
|
case ir.OLITERAL, ir.ONIL, ir.OTYPE:
|
||||||
if n.Sym != nil {
|
if n.Sym() != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !n.Pos.IsKnown() {
|
if !n.Pos().IsKnown() {
|
||||||
if base.Flag.K != 0 {
|
if base.Flag.K != 0 {
|
||||||
base.Warn("setlineno: unknown position (line 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 {
|
func setlineno(n *ir.Node) src.XPos {
|
||||||
lno := base.Pos
|
lno := base.Pos
|
||||||
if n != nil && hasUniquePos(n) {
|
if n != nil && hasUniquePos(n) {
|
||||||
base.Pos = n.Pos
|
base.Pos = n.Pos()
|
||||||
}
|
}
|
||||||
return lno
|
return lno
|
||||||
}
|
}
|
||||||
|
|
@ -95,8 +95,8 @@ func autolabel(prefix string) *types.Sym {
|
||||||
if Curfn == nil {
|
if Curfn == nil {
|
||||||
base.Fatalf("autolabel outside function")
|
base.Fatalf("autolabel outside function")
|
||||||
}
|
}
|
||||||
n := fn.Func.Label
|
n := fn.Func().Label
|
||||||
fn.Func.Label++
|
fn.Func().Label++
|
||||||
return lookupN(prefix, int(n))
|
return lookupN(prefix, int(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,25 +120,25 @@ func importdot(opkg *types.Pkg, pack *ir.Node) {
|
||||||
|
|
||||||
s1.Def = s.Def
|
s1.Def = s.Def
|
||||||
s1.Block = s.Block
|
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))
|
ir.Dump("s1def", ir.AsNode(s1.Def))
|
||||||
base.Fatalf("missing Name")
|
base.Fatalf("missing Name")
|
||||||
}
|
}
|
||||||
ir.AsNode(s1.Def).Name.Pack = pack
|
ir.AsNode(s1.Def).Name().Pack = pack
|
||||||
s1.Origpkg = opkg
|
s1.Origpkg = opkg
|
||||||
n++
|
n++
|
||||||
}
|
}
|
||||||
|
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
// can't possibly be used - there were no symbols
|
// 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.
|
// newname returns a new ONAME Node associated with symbol s.
|
||||||
func NewName(s *types.Sym) *ir.Node {
|
func NewName(s *types.Sym) *ir.Node {
|
||||||
n := ir.NewNameAt(base.Pos, s)
|
n := ir.NewNameAt(base.Pos, s)
|
||||||
n.Name.Curfn = Curfn
|
n.Name().Curfn = Curfn
|
||||||
return n
|
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.
|
// 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 {
|
func nodlSym(pos src.XPos, op ir.Op, left *ir.Node, sym *types.Sym) *ir.Node {
|
||||||
n := ir.NodAt(pos, op, left, nil)
|
n := ir.NodAt(pos, op, left, nil)
|
||||||
n.Sym = sym
|
n.SetSym(sym)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,7 +169,7 @@ func nodintconst(v int64) *ir.Node {
|
||||||
|
|
||||||
func nodnil() *ir.Node {
|
func nodnil() *ir.Node {
|
||||||
n := ir.Nod(ir.ONIL, nil, nil)
|
n := ir.Nod(ir.ONIL, nil, nil)
|
||||||
n.Type = types.Types[types.TNIL]
|
n.SetType(types.Types[types.TNIL])
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,16 +190,16 @@ func treecopy(n *ir.Node, pos src.XPos) *ir.Node {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
default:
|
default:
|
||||||
m := ir.SepCopy(n)
|
m := ir.SepCopy(n)
|
||||||
m.Left = treecopy(n.Left, pos)
|
m.SetLeft(treecopy(n.Left(), pos))
|
||||||
m.Right = treecopy(n.Right, pos)
|
m.SetRight(treecopy(n.Right(), pos))
|
||||||
m.List.Set(listtreecopy(n.List.Slice(), pos))
|
m.PtrList().Set(listtreecopy(n.List().Slice(), pos))
|
||||||
if pos.IsKnown() {
|
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)
|
ir.Dump("treecopy", n)
|
||||||
base.Fatalf("treecopy Name")
|
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.
|
// Convert node n for assignment to type t.
|
||||||
func assignconvfn(n *ir.Node, t *types.Type, context func() string) *ir.Node {
|
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
|
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")
|
base.Errorf("use of untyped nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
n = convlit1(n, t, false, context)
|
n = convlit1(n, t, false, context)
|
||||||
if n.Type == nil {
|
if n.Type() == nil {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
if t.Etype == types.TBLANK {
|
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
|
// Convert ideal bool from comparison to plain bool
|
||||||
// if the next step is non-bool (like interface{}).
|
// if the next step is non-bool (like interface{}).
|
||||||
if n.Type == types.UntypedBool && !t.IsBoolean() {
|
if n.Type() == types.UntypedBool && !t.IsBoolean() {
|
||||||
if n.Op == ir.ONAME || n.Op == ir.OLITERAL {
|
if n.Op() == ir.ONAME || n.Op() == ir.OLITERAL {
|
||||||
r := ir.Nod(ir.OCONVNOP, n, nil)
|
r := ir.Nod(ir.OCONVNOP, n, nil)
|
||||||
r.Type = types.Types[types.TBOOL]
|
r.SetType(types.Types[types.TBOOL])
|
||||||
r.SetTypecheck(1)
|
r.SetTypecheck(1)
|
||||||
r.SetImplicit(true)
|
r.SetImplicit(true)
|
||||||
n = r
|
n = r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if types.Identical(n.Type, t) {
|
if types.Identical(n.Type(), t) {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
op, why := assignop(n.Type, t)
|
op, why := assignop(n.Type(), t)
|
||||||
if op == ir.OXXX {
|
if op == ir.OXXX {
|
||||||
base.Errorf("cannot use %L as type %v in %s%s", n, t, context(), why)
|
base.Errorf("cannot use %L as type %v in %s%s", n, t, context(), why)
|
||||||
op = ir.OCONV
|
op = ir.OCONV
|
||||||
}
|
}
|
||||||
|
|
||||||
r := ir.Nod(op, n, nil)
|
r := ir.Nod(op, n, nil)
|
||||||
r.Type = t
|
r.SetType(t)
|
||||||
r.SetTypecheck(1)
|
r.SetTypecheck(1)
|
||||||
r.SetImplicit(true)
|
r.SetImplicit(true)
|
||||||
r.Orig = n.Orig
|
r.SetOrig(n.Orig())
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -572,27 +572,27 @@ func backingArrayPtrLen(n *ir.Node) (ptr, len *ir.Node) {
|
||||||
base.Fatalf("backingArrayPtrLen not cheap: %v", n)
|
base.Fatalf("backingArrayPtrLen not cheap: %v", n)
|
||||||
}
|
}
|
||||||
ptr = ir.Nod(ir.OSPTR, n, nil)
|
ptr = ir.Nod(ir.OSPTR, n, nil)
|
||||||
if n.Type.IsString() {
|
if n.Type().IsString() {
|
||||||
ptr.Type = types.Types[types.TUINT8].PtrTo()
|
ptr.SetType(types.Types[types.TUINT8].PtrTo())
|
||||||
} else {
|
} else {
|
||||||
ptr.Type = n.Type.Elem().PtrTo()
|
ptr.SetType(n.Type().Elem().PtrTo())
|
||||||
}
|
}
|
||||||
len = ir.Nod(ir.OLEN, n, nil)
|
len = ir.Nod(ir.OLEN, n, nil)
|
||||||
len.Type = types.Types[types.TINT]
|
len.SetType(types.Types[types.TINT])
|
||||||
return ptr, len
|
return ptr, len
|
||||||
}
|
}
|
||||||
|
|
||||||
// labeledControl returns the control flow Node (for, switch, select)
|
// labeledControl returns the control flow Node (for, switch, select)
|
||||||
// associated with the label n, if any.
|
// associated with the label n, if any.
|
||||||
func labeledControl(n *ir.Node) *ir.Node {
|
func labeledControl(n *ir.Node) *ir.Node {
|
||||||
if n.Op != ir.OLABEL {
|
if n.Op() != ir.OLABEL {
|
||||||
base.Fatalf("labeledControl %v", n.Op)
|
base.Fatalf("labeledControl %v", n.Op())
|
||||||
}
|
}
|
||||||
ctl := n.Name.Defn
|
ctl := n.Name().Defn
|
||||||
if ctl == nil {
|
if ctl == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
switch ctl.Op {
|
switch ctl.Op() {
|
||||||
case ir.OFOR, ir.OFORUNTIL, ir.OSWITCH, ir.OSELECT:
|
case ir.OFOR, ir.OFORUNTIL, ir.OSWITCH, ir.OSELECT:
|
||||||
return ctl
|
return ctl
|
||||||
}
|
}
|
||||||
|
|
@ -626,12 +626,12 @@ func updateHasCall(n *ir.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func calcHasCall(n *ir.Node) bool {
|
func calcHasCall(n *ir.Node) bool {
|
||||||
if n.Ninit.Len() != 0 {
|
if n.Init().Len() != 0 {
|
||||||
// TODO(mdempsky): This seems overly conservative.
|
// TODO(mdempsky): This seems overly conservative.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.OLITERAL, ir.ONIL, ir.ONAME, ir.OTYPE:
|
case ir.OLITERAL, ir.ONIL, ir.ONAME, ir.OTYPE:
|
||||||
if n.HasCall() {
|
if n.HasCall() {
|
||||||
base.Fatalf("OLITERAL/ONAME/OTYPE should never have calls: %+v", n)
|
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
|
// When using soft-float, these ops might be rewritten to function calls
|
||||||
// so we ensure they are evaluated first.
|
// so we ensure they are evaluated first.
|
||||||
case ir.OADD, ir.OSUB, ir.ONEG, ir.OMUL:
|
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
|
return true
|
||||||
}
|
}
|
||||||
case ir.OLT, ir.OEQ, ir.ONE, ir.OLE, ir.OGE, ir.OGT:
|
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
|
return true
|
||||||
}
|
}
|
||||||
case ir.OCONV:
|
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
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Left != nil && n.Left.HasCall() {
|
if n.Left() != nil && n.Left().HasCall() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if n.Right != nil && n.Right.HasCall() {
|
if n.Right() != nil && n.Right().HasCall() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
@ -745,45 +745,45 @@ func safeexpr(n *ir.Node, init *ir.Nodes) *ir.Node {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Ninit.Len() != 0 {
|
if n.Init().Len() != 0 {
|
||||||
walkstmtlist(n.Ninit.Slice())
|
walkstmtlist(n.Init().Slice())
|
||||||
init.AppendNodes(&n.Ninit)
|
init.AppendNodes(n.PtrInit())
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.ONAME, ir.OLITERAL, ir.ONIL:
|
case ir.ONAME, ir.OLITERAL, ir.ONIL:
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.ODOT, ir.OLEN, ir.OCAP:
|
case ir.ODOT, ir.OLEN, ir.OCAP:
|
||||||
l := safeexpr(n.Left, init)
|
l := safeexpr(n.Left(), init)
|
||||||
if l == n.Left {
|
if l == n.Left() {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
r := ir.Copy(n)
|
r := ir.Copy(n)
|
||||||
r.Left = l
|
r.SetLeft(l)
|
||||||
r = typecheck(r, ctxExpr)
|
r = typecheck(r, ctxExpr)
|
||||||
r = walkexpr(r, init)
|
r = walkexpr(r, init)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
case ir.ODOTPTR, ir.ODEREF:
|
case ir.ODOTPTR, ir.ODEREF:
|
||||||
l := safeexpr(n.Left, init)
|
l := safeexpr(n.Left(), init)
|
||||||
if l == n.Left {
|
if l == n.Left() {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
a := ir.Copy(n)
|
a := ir.Copy(n)
|
||||||
a.Left = l
|
a.SetLeft(l)
|
||||||
a = walkexpr(a, init)
|
a = walkexpr(a, init)
|
||||||
return a
|
return a
|
||||||
|
|
||||||
case ir.OINDEX, ir.OINDEXMAP:
|
case ir.OINDEX, ir.OINDEXMAP:
|
||||||
l := safeexpr(n.Left, init)
|
l := safeexpr(n.Left(), init)
|
||||||
r := safeexpr(n.Right, init)
|
r := safeexpr(n.Right(), init)
|
||||||
if l == n.Left && r == n.Right {
|
if l == n.Left() && r == n.Right() {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
a := ir.Copy(n)
|
a := ir.Copy(n)
|
||||||
a.Left = l
|
a.SetLeft(l)
|
||||||
a.Right = r
|
a.SetRight(r)
|
||||||
a = walkexpr(a, init)
|
a = walkexpr(a, init)
|
||||||
return a
|
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.
|
// return side-effect free and cheap n, appending side effects to init.
|
||||||
// result may not be assignable.
|
// result may not be assignable.
|
||||||
func cheapexpr(n *ir.Node, init *ir.Nodes) *ir.Node {
|
func cheapexpr(n *ir.Node, init *ir.Nodes) *ir.Node {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.ONAME, ir.OLITERAL, ir.ONIL:
|
case ir.ONAME, ir.OLITERAL, ir.ONIL:
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
return copyexpr(n, n.Type, init)
|
return copyexpr(n, n.Type(), init)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Code to resolve elided DOTs in embedded types.
|
// 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.
|
// will give shortest unique addressing.
|
||||||
// modify the tree with missing type names.
|
// modify the tree with missing type names.
|
||||||
func adddot(n *ir.Node) *ir.Node {
|
func adddot(n *ir.Node) *ir.Node {
|
||||||
n.Left = typecheck(n.Left, ctxType|ctxExpr)
|
n.SetLeft(typecheck(n.Left(), ctxType|ctxExpr))
|
||||||
if n.Left.Diag() {
|
if n.Left().Diag() {
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
}
|
}
|
||||||
t := n.Left.Type
|
t := n.Left().Type()
|
||||||
if t == nil {
|
if t == nil {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Left.Op == ir.OTYPE {
|
if n.Left().Op() == ir.OTYPE {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
s := n.Sym
|
s := n.Sym()
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -980,12 +980,12 @@ func adddot(n *ir.Node) *ir.Node {
|
||||||
case path != nil:
|
case path != nil:
|
||||||
// rebuild elided dots
|
// rebuild elided dots
|
||||||
for c := len(path) - 1; c >= 0; c-- {
|
for c := len(path) - 1; c >= 0; c-- {
|
||||||
n.Left = nodSym(ir.ODOT, n.Left, path[c].field.Sym)
|
n.SetLeft(nodSym(ir.ODOT, n.Left(), path[c].field.Sym))
|
||||||
n.Left.SetImplicit(true)
|
n.Left().SetImplicit(true)
|
||||||
}
|
}
|
||||||
case ambig:
|
case ambig:
|
||||||
base.Errorf("ambiguous selector %v", n)
|
base.Errorf("ambiguous selector %v", n)
|
||||||
n.Left = nil
|
n.SetLeft(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return n
|
return n
|
||||||
|
|
@ -1127,7 +1127,7 @@ func structargs(tl *types.Type, mustname bool) []*ir.Node {
|
||||||
gen++
|
gen++
|
||||||
}
|
}
|
||||||
a := symfield(s, t.Type)
|
a := symfield(s, t.Type)
|
||||||
a.Pos = t.Pos
|
a.SetPos(t.Pos)
|
||||||
a.SetIsDDD(t.IsDDD())
|
a.SetIsDDD(t.IsDDD())
|
||||||
args = append(args, a)
|
args = append(args, a)
|
||||||
}
|
}
|
||||||
|
|
@ -1177,14 +1177,14 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
|
||||||
dclcontext = ir.PEXTERN
|
dclcontext = ir.PEXTERN
|
||||||
|
|
||||||
tfn := ir.Nod(ir.OTFUNC, nil, nil)
|
tfn := ir.Nod(ir.OTFUNC, nil, nil)
|
||||||
tfn.Left = namedfield(".this", rcvr)
|
tfn.SetLeft(namedfield(".this", rcvr))
|
||||||
tfn.List.Set(structargs(method.Type.Params(), true))
|
tfn.PtrList().Set(structargs(method.Type.Params(), true))
|
||||||
tfn.Rlist.Set(structargs(method.Type.Results(), false))
|
tfn.PtrRlist().Set(structargs(method.Type.Results(), false))
|
||||||
|
|
||||||
fn := dclfunc(newnam, tfn)
|
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
|
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 {
|
if rcvr.IsPtr() && rcvr.Elem() == methodrcvr {
|
||||||
// generating wrapper from *T to T.
|
// generating wrapper from *T to T.
|
||||||
n := ir.Nod(ir.OIF, nil, nil)
|
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)
|
call := ir.Nod(ir.OCALL, syslook("panicwrap"), nil)
|
||||||
n.Nbody.Set1(call)
|
n.PtrBody().Set1(call)
|
||||||
fn.Nbody.Append(n)
|
fn.PtrBody().Append(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
dot := adddot(nodSym(ir.OXDOT, nthis, method.Sym))
|
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.
|
// value for that function.
|
||||||
if !instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !isifacemethod(method.Type) && !(thearch.LinkArch.Name == "ppc64le" && base.Ctxt.Flag_dynlink) {
|
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.
|
// 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.
|
// TODO(mdempsky): Remove dependency on dotlist.
|
||||||
if !dotlist[0].field.Type.IsPtr() {
|
if !dotlist[0].field.Type.IsPtr() {
|
||||||
dot = ir.Nod(ir.OADDR, dot, nil)
|
dot = ir.Nod(ir.OADDR, dot, nil)
|
||||||
}
|
}
|
||||||
as := ir.Nod(ir.OAS, nthis, convnop(dot, rcvr))
|
as := ir.Nod(ir.OAS, nthis, convnop(dot, rcvr))
|
||||||
fn.Nbody.Append(as)
|
fn.PtrBody().Append(as)
|
||||||
fn.Nbody.Append(nodSym(ir.ORETJMP, nil, methodSym(methodrcvr, method.Sym)))
|
fn.PtrBody().Append(nodSym(ir.ORETJMP, nil, methodSym(methodrcvr, method.Sym)))
|
||||||
} else {
|
} 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 := ir.Nod(ir.OCALL, dot, nil)
|
||||||
call.List.Set(paramNnames(tfn.Type))
|
call.PtrList().Set(paramNnames(tfn.Type()))
|
||||||
call.SetIsDDD(tfn.Type.IsVariadic())
|
call.SetIsDDD(tfn.Type().IsVariadic())
|
||||||
if method.Type.NumResults() > 0 {
|
if method.Type.NumResults() > 0 {
|
||||||
n := ir.Nod(ir.ORETURN, nil, nil)
|
n := ir.Nod(ir.ORETURN, nil, nil)
|
||||||
n.List.Set1(call)
|
n.PtrList().Set1(call)
|
||||||
call = n
|
call = n
|
||||||
}
|
}
|
||||||
fn.Nbody.Append(call)
|
fn.PtrBody().Append(call)
|
||||||
}
|
}
|
||||||
|
|
||||||
if false && base.Flag.LowerR != 0 {
|
if false && base.Flag.LowerR != 0 {
|
||||||
ir.DumpList("genwrapper body", fn.Nbody)
|
ir.DumpList("genwrapper body", fn.Body())
|
||||||
}
|
}
|
||||||
|
|
||||||
funcbody()
|
funcbody()
|
||||||
|
|
@ -1242,7 +1242,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
|
||||||
fn = typecheck(fn, ctxStmt)
|
fn = typecheck(fn, ctxStmt)
|
||||||
|
|
||||||
Curfn = fn
|
Curfn = fn
|
||||||
typecheckslice(fn.Nbody.Slice(), ctxStmt)
|
typecheckslice(fn.Body().Slice(), ctxStmt)
|
||||||
|
|
||||||
// Inline calls within (*T).M wrappers. This is safe because we only
|
// Inline calls within (*T).M wrappers. This is safe because we only
|
||||||
// generate those wrappers within the same compilation unit as (T).M.
|
// 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)
|
n := NewName(sym)
|
||||||
setNodeNameFunc(n)
|
setNodeNameFunc(n)
|
||||||
n.Type = functype(nil, []*ir.Node{
|
n.SetType(functype(nil, []*ir.Node{
|
||||||
anonfield(types.NewPtr(t)),
|
anonfield(types.NewPtr(t)),
|
||||||
anonfield(types.Types[types.TUINTPTR]),
|
anonfield(types.Types[types.TUINTPTR]),
|
||||||
anonfield(types.Types[types.TUINTPTR]),
|
anonfield(types.Types[types.TUINTPTR]),
|
||||||
}, []*ir.Node{
|
}, []*ir.Node{
|
||||||
anonfield(types.Types[types.TUINTPTR]),
|
anonfield(types.Types[types.TUINTPTR]),
|
||||||
})
|
}))
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1403,16 +1403,16 @@ func listtreecopy(l []*ir.Node, pos src.XPos) []*ir.Node {
|
||||||
|
|
||||||
func liststmt(l []*ir.Node) *ir.Node {
|
func liststmt(l []*ir.Node) *ir.Node {
|
||||||
n := ir.Nod(ir.OBLOCK, nil, nil)
|
n := ir.Nod(ir.OBLOCK, nil, nil)
|
||||||
n.List.Set(l)
|
n.PtrList().Set(l)
|
||||||
if len(l) != 0 {
|
if len(l) != 0 {
|
||||||
n.Pos = l[0].Pos
|
n.SetPos(l[0].Pos())
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func ngotype(n *ir.Node) *types.Sym {
|
func ngotype(n *ir.Node) *types.Sym {
|
||||||
if n.Type != nil {
|
if n.Type() != nil {
|
||||||
return typenamesym(n.Type)
|
return typenamesym(n.Type())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -1426,11 +1426,11 @@ func addinit(n *ir.Node, init []*ir.Node) *ir.Node {
|
||||||
if ir.MayBeShared(n) {
|
if ir.MayBeShared(n) {
|
||||||
// Introduce OCONVNOP to hold init list.
|
// Introduce OCONVNOP to hold init list.
|
||||||
n = ir.Nod(ir.OCONVNOP, n, nil)
|
n = ir.Nod(ir.OCONVNOP, n, nil)
|
||||||
n.Type = n.Left.Type
|
n.SetType(n.Left().Type())
|
||||||
n.SetTypecheck(1)
|
n.SetTypecheck(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Ninit.Prepend(init...)
|
n.PtrInit().Prepend(init...)
|
||||||
n.SetHasCall(true)
|
n.SetHasCall(true)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -1520,10 +1520,10 @@ func isdirectiface(t *types.Type) bool {
|
||||||
// itabType loads the _type field from a runtime.itab struct.
|
// itabType loads the _type field from a runtime.itab struct.
|
||||||
func itabType(itab *ir.Node) *ir.Node {
|
func itabType(itab *ir.Node) *ir.Node {
|
||||||
typ := nodSym(ir.ODOTPTR, itab, nil)
|
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.SetTypecheck(1)
|
||||||
typ.Xoffset = int64(Widthptr) // offset of _type in runtime.itab
|
typ.SetOffset(int64(Widthptr)) // offset of _type in runtime.itab
|
||||||
typ.SetBounded(true) // guaranteed not to fault
|
typ.SetBounded(true) // guaranteed not to fault
|
||||||
return typ
|
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)
|
ptr := nodlSym(pos, ir.OIDATA, n, nil)
|
||||||
if isdirectiface(t) {
|
if isdirectiface(t) {
|
||||||
ptr.Type = t
|
ptr.SetType(t)
|
||||||
ptr.SetTypecheck(1)
|
ptr.SetTypecheck(1)
|
||||||
return ptr
|
return ptr
|
||||||
}
|
}
|
||||||
ptr.Type = types.NewPtr(t)
|
ptr.SetType(types.NewPtr(t))
|
||||||
ptr.SetTypecheck(1)
|
ptr.SetTypecheck(1)
|
||||||
ind := ir.NodAt(pos, ir.ODEREF, ptr, nil)
|
ind := ir.NodAt(pos, ir.ODEREF, ptr, nil)
|
||||||
ind.Type = t
|
ind.SetType(t)
|
||||||
ind.SetTypecheck(1)
|
ind.SetTypecheck(1)
|
||||||
ind.SetBounded(true)
|
ind.SetBounded(true)
|
||||||
return ind
|
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.
|
// This is where t was declared or where it appeared as a type expression.
|
||||||
func typePos(t *types.Type) src.XPos {
|
func typePos(t *types.Type) src.XPos {
|
||||||
n := ir.AsNode(t.Nod)
|
n := ir.AsNode(t.Nod)
|
||||||
if n == nil || !n.Pos.IsKnown() {
|
if n == nil || !n.Pos().IsKnown() {
|
||||||
base.Fatalf("bad type: %v", t)
|
base.Fatalf("bad type: %v", t)
|
||||||
}
|
}
|
||||||
return n.Pos
|
return n.Pos()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ import (
|
||||||
|
|
||||||
// typecheckswitch typechecks a switch statement.
|
// typecheckswitch typechecks a switch statement.
|
||||||
func typecheckswitch(n *ir.Node) {
|
func typecheckswitch(n *ir.Node) {
|
||||||
typecheckslice(n.Ninit.Slice(), ctxStmt)
|
typecheckslice(n.Init().Slice(), ctxStmt)
|
||||||
if n.Left != nil && n.Left.Op == ir.OTYPESW {
|
if n.Left() != nil && n.Left().Op() == ir.OTYPESW {
|
||||||
typecheckTypeSwitch(n)
|
typecheckTypeSwitch(n)
|
||||||
} else {
|
} else {
|
||||||
typecheckExprSwitch(n)
|
typecheckExprSwitch(n)
|
||||||
|
|
@ -25,27 +25,27 @@ func typecheckswitch(n *ir.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func typecheckTypeSwitch(n *ir.Node) {
|
func typecheckTypeSwitch(n *ir.Node) {
|
||||||
n.Left.Right = typecheck(n.Left.Right, ctxExpr)
|
n.Left().SetRight(typecheck(n.Left().Right(), ctxExpr))
|
||||||
t := n.Left.Right.Type
|
t := n.Left().Right().Type()
|
||||||
if t != nil && !t.IsInterface() {
|
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
|
t = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't actually declare the type switch's guarded
|
// We don't actually declare the type switch's guarded
|
||||||
// declaration itself. So if there are no cases, we won't
|
// declaration itself. So if there are no cases, we won't
|
||||||
// notice that it went unused.
|
// notice that it went unused.
|
||||||
if v := n.Left.Left; v != nil && !ir.IsBlank(v) && n.List.Len() == 0 {
|
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)
|
base.ErrorfAt(v.Pos(), "%v declared but not used", v.Sym())
|
||||||
}
|
}
|
||||||
|
|
||||||
var defCase, nilCase *ir.Node
|
var defCase, nilCase *ir.Node
|
||||||
var ts typeSet
|
var ts typeSet
|
||||||
for _, ncase := range n.List.Slice() {
|
for _, ncase := range n.List().Slice() {
|
||||||
ls := ncase.List.Slice()
|
ls := ncase.List().Slice()
|
||||||
if len(ls) == 0 { // default:
|
if len(ls) == 0 { // default:
|
||||||
if defCase != nil {
|
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 {
|
} else {
|
||||||
defCase = ncase
|
defCase = ncase
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +54,7 @@ func typecheckTypeSwitch(n *ir.Node) {
|
||||||
for i := range ls {
|
for i := range ls {
|
||||||
ls[i] = typecheck(ls[i], ctxExpr|ctxType)
|
ls[i] = typecheck(ls[i], ctxExpr|ctxType)
|
||||||
n1 := ls[i]
|
n1 := ls[i]
|
||||||
if t == nil || n1.Type == nil {
|
if t == nil || n1.Type() == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,36 +63,36 @@ func typecheckTypeSwitch(n *ir.Node) {
|
||||||
switch {
|
switch {
|
||||||
case ir.IsNil(n1): // case nil:
|
case ir.IsNil(n1): // case nil:
|
||||||
if nilCase != 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 {
|
} else {
|
||||||
nilCase = ncase
|
nilCase = ncase
|
||||||
}
|
}
|
||||||
case n1.Op != ir.OTYPE:
|
case n1.Op() != ir.OTYPE:
|
||||||
base.ErrorfAt(ncase.Pos, "%L is not a type", n1)
|
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.Type().IsInterface() && !implements(n1.Type(), t, &missing, &have, &ptr) && !missing.Broke():
|
||||||
if have != nil && !have.Broke() {
|
if have != nil && !have.Broke() {
|
||||||
base.ErrorfAt(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
|
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)
|
" (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 {
|
} else if ptr != 0 {
|
||||||
base.ErrorfAt(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
|
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)
|
" (%v method has pointer receiver)", n.Left().Right(), n1.Type(), missing.Sym)
|
||||||
} else {
|
} else {
|
||||||
base.ErrorfAt(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
|
base.ErrorfAt(ncase.Pos(), "impossible type switch case: %L cannot have dynamic type %v"+
|
||||||
" (missing %v method)", n.Left.Right, n1.Type, missing.Sym)
|
" (missing %v method)", n.Left().Right(), n1.Type(), missing.Sym)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if n1.Op == ir.OTYPE {
|
if n1.Op() == ir.OTYPE {
|
||||||
ts.add(ncase.Pos, n1.Type)
|
ts.add(ncase.Pos(), n1.Type())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ncase.Rlist.Len() != 0 {
|
if ncase.Rlist().Len() != 0 {
|
||||||
// Assign the clause variable's type.
|
// Assign the clause variable's type.
|
||||||
vt := t
|
vt := t
|
||||||
if len(ls) == 1 {
|
if len(ls) == 1 {
|
||||||
if ls[0].Op == ir.OTYPE {
|
if ls[0].Op() == ir.OTYPE {
|
||||||
vt = ls[0].Type
|
vt = ls[0].Type()
|
||||||
} else if !ir.IsNil(ls[0]) {
|
} else if !ir.IsNil(ls[0]) {
|
||||||
// Invalid single-type case;
|
// Invalid single-type case;
|
||||||
// mark variable as broken.
|
// mark variable as broken.
|
||||||
|
|
@ -100,8 +100,8 @@ func typecheckTypeSwitch(n *ir.Node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nvar := ncase.Rlist.First()
|
nvar := ncase.Rlist().First()
|
||||||
nvar.Type = vt
|
nvar.SetType(vt)
|
||||||
if vt != nil {
|
if vt != nil {
|
||||||
nvar = typecheck(nvar, ctxExpr|ctxAssign)
|
nvar = typecheck(nvar, ctxExpr|ctxAssign)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -109,10 +109,10 @@ func typecheckTypeSwitch(n *ir.Node) {
|
||||||
nvar.SetTypecheck(1)
|
nvar.SetTypecheck(1)
|
||||||
nvar.SetWalkdef(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) {
|
func typecheckExprSwitch(n *ir.Node) {
|
||||||
t := types.Types[types.TBOOL]
|
t := types.Types[types.TBOOL]
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
n.Left = typecheck(n.Left, ctxExpr)
|
n.SetLeft(typecheck(n.Left(), ctxExpr))
|
||||||
n.Left = defaultlit(n.Left, nil)
|
n.SetLeft(defaultlit(n.Left(), nil))
|
||||||
t = n.Left.Type
|
t = n.Left().Type()
|
||||||
}
|
}
|
||||||
|
|
||||||
var nilonly string
|
var nilonly string
|
||||||
|
|
@ -164,9 +164,9 @@ func typecheckExprSwitch(n *ir.Node) {
|
||||||
|
|
||||||
case !IsComparable(t):
|
case !IsComparable(t):
|
||||||
if t.IsStruct() {
|
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 {
|
} else {
|
||||||
base.ErrorfAt(n.Pos, "cannot switch on %L", n.Left)
|
base.ErrorfAt(n.Pos(), "cannot switch on %L", n.Left())
|
||||||
}
|
}
|
||||||
t = nil
|
t = nil
|
||||||
}
|
}
|
||||||
|
|
@ -174,11 +174,11 @@ func typecheckExprSwitch(n *ir.Node) {
|
||||||
|
|
||||||
var defCase *ir.Node
|
var defCase *ir.Node
|
||||||
var cs constSet
|
var cs constSet
|
||||||
for _, ncase := range n.List.Slice() {
|
for _, ncase := range n.List().Slice() {
|
||||||
ls := ncase.List.Slice()
|
ls := ncase.List().Slice()
|
||||||
if len(ls) == 0 { // default:
|
if len(ls) == 0 { // default:
|
||||||
if defCase != nil {
|
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 {
|
} else {
|
||||||
defCase = ncase
|
defCase = ncase
|
||||||
}
|
}
|
||||||
|
|
@ -189,22 +189,22 @@ func typecheckExprSwitch(n *ir.Node) {
|
||||||
ls[i] = typecheck(ls[i], ctxExpr)
|
ls[i] = typecheck(ls[i], ctxExpr)
|
||||||
ls[i] = defaultlit(ls[i], t)
|
ls[i] = defaultlit(ls[i], t)
|
||||||
n1 := ls[i]
|
n1 := ls[i]
|
||||||
if t == nil || n1.Type == nil {
|
if t == nil || n1.Type() == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if nilonly != "" && !ir.IsNil(n1) {
|
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)
|
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) {
|
} 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 %L in switch (incomparable type)", n1)
|
||||||
} else {
|
} else {
|
||||||
op1, _ := assignop(n1.Type, t)
|
op1, _ := assignop(n1.Type(), t)
|
||||||
op2, _ := assignop(t, n1.Type)
|
op2, _ := assignop(t, n1.Type())
|
||||||
if op1 == ir.OXXX && op2 == ir.OXXX {
|
if op1 == ir.OXXX && op2 == ir.OXXX {
|
||||||
if n.Left != nil {
|
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)
|
base.ErrorfAt(ncase.Pos(), "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left(), n1.Type(), t)
|
||||||
} else {
|
} 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" && GOARM == "5":
|
||||||
// case GOARCH == "arm":
|
// case GOARCH == "arm":
|
||||||
// which would both evaluate to false for non-ARM compiles.
|
// which would both evaluate to false for non-ARM compiles.
|
||||||
if !n1.Type.IsBoolean() {
|
if !n1.Type().IsBoolean() {
|
||||||
cs.add(ncase.Pos, n1, "case", "switch")
|
cs.add(ncase.Pos(), n1, "case", "switch")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typecheckslice(ncase.Nbody.Slice(), ctxStmt)
|
typecheckslice(ncase.Body().Slice(), ctxStmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// walkswitch walks a switch statement.
|
// walkswitch walks a switch statement.
|
||||||
func walkswitch(sw *ir.Node) {
|
func walkswitch(sw *ir.Node) {
|
||||||
// Guard against double walk, see #25776.
|
// 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
|
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)
|
walkTypeSwitch(sw)
|
||||||
} else {
|
} else {
|
||||||
walkExprSwitch(sw)
|
walkExprSwitch(sw)
|
||||||
|
|
@ -243,8 +243,8 @@ func walkswitch(sw *ir.Node) {
|
||||||
func walkExprSwitch(sw *ir.Node) {
|
func walkExprSwitch(sw *ir.Node) {
|
||||||
lno := setlineno(sw)
|
lno := setlineno(sw)
|
||||||
|
|
||||||
cond := sw.Left
|
cond := sw.Left()
|
||||||
sw.Left = nil
|
sw.SetLeft(nil)
|
||||||
|
|
||||||
// convert switch {...} to switch true {...}
|
// convert switch {...} to switch true {...}
|
||||||
if cond == nil {
|
if cond == nil {
|
||||||
|
|
@ -260,13 +260,13 @@ func walkExprSwitch(sw *ir.Node) {
|
||||||
// because walkexpr will lower the string
|
// because walkexpr will lower the string
|
||||||
// conversion into a runtime call.
|
// conversion into a runtime call.
|
||||||
// See issue 24937 for more discussion.
|
// See issue 24937 for more discussion.
|
||||||
if cond.Op == ir.OBYTES2STR && allCaseExprsAreSideEffectFree(sw) {
|
if cond.Op() == ir.OBYTES2STR && allCaseExprsAreSideEffectFree(sw) {
|
||||||
cond.Op = ir.OBYTES2STRTMP
|
cond.SetOp(ir.OBYTES2STRTMP)
|
||||||
}
|
}
|
||||||
|
|
||||||
cond = walkexpr(cond, &sw.Ninit)
|
cond = walkexpr(cond, sw.PtrInit())
|
||||||
if cond.Op != ir.OLITERAL && cond.Op != ir.ONIL {
|
if cond.Op() != ir.OLITERAL && cond.Op() != ir.ONIL {
|
||||||
cond = copyexpr(cond, cond.Type, &sw.Nbody)
|
cond = copyexpr(cond, cond.Type(), sw.PtrBody())
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Pos = lno
|
base.Pos = lno
|
||||||
|
|
@ -277,43 +277,43 @@ func walkExprSwitch(sw *ir.Node) {
|
||||||
|
|
||||||
var defaultGoto *ir.Node
|
var defaultGoto *ir.Node
|
||||||
var body ir.Nodes
|
var body ir.Nodes
|
||||||
for _, ncase := range sw.List.Slice() {
|
for _, ncase := range sw.List().Slice() {
|
||||||
label := autolabel(".s")
|
label := autolabel(".s")
|
||||||
jmp := npos(ncase.Pos, nodSym(ir.OGOTO, nil, label))
|
jmp := npos(ncase.Pos(), nodSym(ir.OGOTO, nil, label))
|
||||||
|
|
||||||
// Process case dispatch.
|
// Process case dispatch.
|
||||||
if ncase.List.Len() == 0 {
|
if ncase.List().Len() == 0 {
|
||||||
if defaultGoto != nil {
|
if defaultGoto != nil {
|
||||||
base.Fatalf("duplicate default case not detected during typechecking")
|
base.Fatalf("duplicate default case not detected during typechecking")
|
||||||
}
|
}
|
||||||
defaultGoto = jmp
|
defaultGoto = jmp
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, n1 := range ncase.List.Slice() {
|
for _, n1 := range ncase.List().Slice() {
|
||||||
s.Add(ncase.Pos, n1, jmp)
|
s.Add(ncase.Pos(), n1, jmp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process body.
|
// Process body.
|
||||||
body.Append(npos(ncase.Pos, nodSym(ir.OLABEL, nil, label)))
|
body.Append(npos(ncase.Pos(), nodSym(ir.OLABEL, nil, label)))
|
||||||
body.Append(ncase.Nbody.Slice()...)
|
body.Append(ncase.Body().Slice()...)
|
||||||
if fall, pos := hasFall(ncase.Nbody.Slice()); !fall {
|
if fall, pos := hasFall(ncase.Body().Slice()); !fall {
|
||||||
br := ir.Nod(ir.OBREAK, nil, nil)
|
br := ir.Nod(ir.OBREAK, nil, nil)
|
||||||
br.Pos = pos
|
br.SetPos(pos)
|
||||||
body.Append(br)
|
body.Append(br)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sw.List.Set(nil)
|
sw.PtrList().Set(nil)
|
||||||
|
|
||||||
if defaultGoto == nil {
|
if defaultGoto == nil {
|
||||||
br := ir.Nod(ir.OBREAK, nil, nil)
|
br := ir.Nod(ir.OBREAK, nil, nil)
|
||||||
br.Pos = br.Pos.WithNotStmt()
|
br.SetPos(br.Pos().WithNotStmt())
|
||||||
defaultGoto = br
|
defaultGoto = br
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Emit(&sw.Nbody)
|
s.Emit(sw.PtrBody())
|
||||||
sw.Nbody.Append(defaultGoto)
|
sw.PtrBody().Append(defaultGoto)
|
||||||
sw.Nbody.AppendNodes(&body)
|
sw.PtrBody().AppendNodes(&body)
|
||||||
walkstmtlist(sw.Nbody.Slice())
|
walkstmtlist(sw.Body().Slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
// An exprSwitch walks an expression switch.
|
// An exprSwitch walks an expression switch.
|
||||||
|
|
@ -332,7 +332,7 @@ type exprClause struct {
|
||||||
|
|
||||||
func (s *exprSwitch) Add(pos src.XPos, expr, jmp *ir.Node) {
|
func (s *exprSwitch) Add(pos src.XPos, expr, jmp *ir.Node) {
|
||||||
c := exprClause{pos: pos, lo: expr, hi: expr, jmp: jmp}
|
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)
|
s.clauses = append(s.clauses, c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -359,7 +359,7 @@ func (s *exprSwitch) flush() {
|
||||||
// (e.g., sort.Slice doesn't need to invoke the less function
|
// (e.g., sort.Slice doesn't need to invoke the less function
|
||||||
// when there's only a single slice element).
|
// 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
|
// Sort strings by length and then by value. It is
|
||||||
// much cheaper to compare lengths than values, and
|
// much cheaper to compare lengths than values, and
|
||||||
// all we need here is consistency. We respect this
|
// all we need here is consistency. We respect this
|
||||||
|
|
@ -395,8 +395,8 @@ func (s *exprSwitch) flush() {
|
||||||
},
|
},
|
||||||
func(i int, nif *ir.Node) {
|
func(i int, nif *ir.Node) {
|
||||||
run := runs[i]
|
run := runs[i]
|
||||||
nif.Left = ir.Nod(ir.OEQ, ir.Nod(ir.OLEN, s.exprname, nil), nodintconst(runLen(run)))
|
nif.SetLeft(ir.Nod(ir.OEQ, ir.Nod(ir.OLEN, s.exprname, nil), nodintconst(runLen(run))))
|
||||||
s.search(run, &nif.Nbody)
|
s.search(run, nif.PtrBody())
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
@ -407,7 +407,7 @@ func (s *exprSwitch) flush() {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Merge consecutive integer cases.
|
// Merge consecutive integer cases.
|
||||||
if s.exprname.Type.IsInteger() {
|
if s.exprname.Type().IsInteger() {
|
||||||
merged := cc[:1]
|
merged := cc[:1]
|
||||||
for _, c := range cc[1:] {
|
for _, c := range cc[1:] {
|
||||||
last := &merged[len(merged)-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) {
|
func(i int, nif *ir.Node) {
|
||||||
c := &cc[i]
|
c := &cc[i]
|
||||||
nif.Left = c.test(s.exprname)
|
nif.SetLeft(c.test(s.exprname))
|
||||||
nif.Nbody.Set1(c.jmp)
|
nif.PtrBody().Set1(c.jmp)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -445,7 +445,7 @@ func (c *exprClause) test(exprname *ir.Node) *ir.Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimize "switch true { ...}" and "switch false { ... }".
|
// 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() {
|
if exprname.BoolVal() {
|
||||||
return c.lo
|
return c.lo
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -464,12 +464,12 @@ func allCaseExprsAreSideEffectFree(sw *ir.Node) bool {
|
||||||
// Restricting to constants is simple and probably powerful
|
// Restricting to constants is simple and probably powerful
|
||||||
// enough.
|
// enough.
|
||||||
|
|
||||||
for _, ncase := range sw.List.Slice() {
|
for _, ncase := range sw.List().Slice() {
|
||||||
if ncase.Op != ir.OCASE {
|
if ncase.Op() != ir.OCASE {
|
||||||
base.Fatalf("switch string(byteslice) bad op: %v", ncase.Op)
|
base.Fatalf("switch string(byteslice) bad op: %v", ncase.Op())
|
||||||
}
|
}
|
||||||
for _, v := range ncase.List.Slice() {
|
for _, v := range ncase.List().Slice() {
|
||||||
if v.Op != ir.OLITERAL {
|
if v.Op() != ir.OLITERAL {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -486,24 +486,24 @@ func hasFall(stmts []*ir.Node) (bool, src.XPos) {
|
||||||
// nodes will be at the end of the list.
|
// nodes will be at the end of the list.
|
||||||
|
|
||||||
i := len(stmts) - 1
|
i := len(stmts) - 1
|
||||||
for i >= 0 && stmts[i].Op == ir.OVARKILL {
|
for i >= 0 && stmts[i].Op() == ir.OVARKILL {
|
||||||
i--
|
i--
|
||||||
}
|
}
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
return false, src.NoXPos
|
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
|
// walkTypeSwitch generates an AST that implements sw, where sw is a
|
||||||
// type switch.
|
// type switch.
|
||||||
func walkTypeSwitch(sw *ir.Node) {
|
func walkTypeSwitch(sw *ir.Node) {
|
||||||
var s typeSwitch
|
var s typeSwitch
|
||||||
s.facename = sw.Left.Right
|
s.facename = sw.Left().Right()
|
||||||
sw.Left = nil
|
sw.SetLeft(nil)
|
||||||
|
|
||||||
s.facename = walkexpr(s.facename, &sw.Ninit)
|
s.facename = walkexpr(s.facename, sw.PtrInit())
|
||||||
s.facename = copyexpr(s.facename, s.facename.Type, &sw.Nbody)
|
s.facename = copyexpr(s.facename, s.facename.Type(), sw.PtrBody())
|
||||||
s.okname = temp(types.Types[types.TBOOL])
|
s.okname = temp(types.Types[types.TBOOL])
|
||||||
|
|
||||||
// Get interface descriptor word.
|
// Get interface descriptor word.
|
||||||
|
|
@ -518,54 +518,54 @@ func walkTypeSwitch(sw *ir.Node) {
|
||||||
// h := e._type.hash
|
// h := e._type.hash
|
||||||
// Use a similar strategy for non-empty interfaces.
|
// Use a similar strategy for non-empty interfaces.
|
||||||
ifNil := ir.Nod(ir.OIF, nil, nil)
|
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.
|
base.Pos = base.Pos.WithNotStmt() // disable statement marks after the first check.
|
||||||
ifNil.Left = typecheck(ifNil.Left, ctxExpr)
|
ifNil.SetLeft(typecheck(ifNil.Left(), ctxExpr))
|
||||||
ifNil.Left = defaultlit(ifNil.Left, nil)
|
ifNil.SetLeft(defaultlit(ifNil.Left(), nil))
|
||||||
// ifNil.Nbody assigned at end.
|
// ifNil.Nbody assigned at end.
|
||||||
sw.Nbody.Append(ifNil)
|
sw.PtrBody().Append(ifNil)
|
||||||
|
|
||||||
// Load hash from type or itab.
|
// Load hash from type or itab.
|
||||||
dotHash := nodSym(ir.ODOTPTR, itab, nil)
|
dotHash := nodSym(ir.ODOTPTR, itab, nil)
|
||||||
dotHash.Type = types.Types[types.TUINT32]
|
dotHash.SetType(types.Types[types.TUINT32])
|
||||||
dotHash.SetTypecheck(1)
|
dotHash.SetTypecheck(1)
|
||||||
if s.facename.Type.IsEmptyInterface() {
|
if s.facename.Type().IsEmptyInterface() {
|
||||||
dotHash.Xoffset = int64(2 * Widthptr) // offset of hash in runtime._type
|
dotHash.SetOffset(int64(2 * Widthptr)) // offset of hash in runtime._type
|
||||||
} else {
|
} 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
|
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)
|
br := ir.Nod(ir.OBREAK, nil, nil)
|
||||||
var defaultGoto, nilGoto *ir.Node
|
var defaultGoto, nilGoto *ir.Node
|
||||||
var body ir.Nodes
|
var body ir.Nodes
|
||||||
for _, ncase := range sw.List.Slice() {
|
for _, ncase := range sw.List().Slice() {
|
||||||
var caseVar *ir.Node
|
var caseVar *ir.Node
|
||||||
if ncase.Rlist.Len() != 0 {
|
if ncase.Rlist().Len() != 0 {
|
||||||
caseVar = ncase.Rlist.First()
|
caseVar = ncase.Rlist().First()
|
||||||
}
|
}
|
||||||
|
|
||||||
// For single-type cases with an interface type,
|
// For single-type cases with an interface type,
|
||||||
// we initialize the case variable as part of the type assertion.
|
// we initialize the case variable as part of the type assertion.
|
||||||
// In other cases, we initialize it in the body.
|
// In other cases, we initialize it in the body.
|
||||||
var singleType *types.Type
|
var singleType *types.Type
|
||||||
if ncase.List.Len() == 1 && ncase.List.First().Op == ir.OTYPE {
|
if ncase.List().Len() == 1 && ncase.List().First().Op() == ir.OTYPE {
|
||||||
singleType = ncase.List.First().Type
|
singleType = ncase.List().First().Type()
|
||||||
}
|
}
|
||||||
caseVarInitialized := false
|
caseVarInitialized := false
|
||||||
|
|
||||||
label := autolabel(".s")
|
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 {
|
if defaultGoto != nil {
|
||||||
base.Fatalf("duplicate default case not detected during typechecking")
|
base.Fatalf("duplicate default case not detected during typechecking")
|
||||||
}
|
}
|
||||||
defaultGoto = jmp
|
defaultGoto = jmp
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, n1 := range ncase.List.Slice() {
|
for _, n1 := range ncase.List().Slice() {
|
||||||
if ir.IsNil(n1) { // case nil:
|
if ir.IsNil(n1) { // case nil:
|
||||||
if nilGoto != nil {
|
if nilGoto != nil {
|
||||||
base.Fatalf("duplicate nil case not detected during typechecking")
|
base.Fatalf("duplicate nil case not detected during typechecking")
|
||||||
|
|
@ -575,14 +575,14 @@ func walkTypeSwitch(sw *ir.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if singleType != nil && singleType.IsInterface() {
|
if singleType != nil && singleType.IsInterface() {
|
||||||
s.Add(ncase.Pos, n1.Type, caseVar, jmp)
|
s.Add(ncase.Pos(), n1.Type(), caseVar, jmp)
|
||||||
caseVarInitialized = true
|
caseVarInitialized = true
|
||||||
} else {
|
} 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 {
|
if caseVar != nil && !caseVarInitialized {
|
||||||
val := s.facename
|
val := s.facename
|
||||||
if singleType != nil {
|
if singleType != nil {
|
||||||
|
|
@ -590,19 +590,19 @@ func walkTypeSwitch(sw *ir.Node) {
|
||||||
if singleType.IsInterface() {
|
if singleType.IsInterface() {
|
||||||
base.Fatalf("singleType interface should have been handled in Add")
|
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{
|
l := []*ir.Node{
|
||||||
ir.NodAt(ncase.Pos, ir.ODCL, caseVar, nil),
|
ir.NodAt(ncase.Pos(), ir.ODCL, caseVar, nil),
|
||||||
ir.NodAt(ncase.Pos, ir.OAS, caseVar, val),
|
ir.NodAt(ncase.Pos(), ir.OAS, caseVar, val),
|
||||||
}
|
}
|
||||||
typecheckslice(l, ctxStmt)
|
typecheckslice(l, ctxStmt)
|
||||||
body.Append(l...)
|
body.Append(l...)
|
||||||
}
|
}
|
||||||
body.Append(ncase.Nbody.Slice()...)
|
body.Append(ncase.Body().Slice()...)
|
||||||
body.Append(br)
|
body.Append(br)
|
||||||
}
|
}
|
||||||
sw.List.Set(nil)
|
sw.PtrList().Set(nil)
|
||||||
|
|
||||||
if defaultGoto == nil {
|
if defaultGoto == nil {
|
||||||
defaultGoto = br
|
defaultGoto = br
|
||||||
|
|
@ -610,13 +610,13 @@ func walkTypeSwitch(sw *ir.Node) {
|
||||||
if nilGoto == nil {
|
if nilGoto == nil {
|
||||||
nilGoto = defaultGoto
|
nilGoto = defaultGoto
|
||||||
}
|
}
|
||||||
ifNil.Nbody.Set1(nilGoto)
|
ifNil.PtrBody().Set1(nilGoto)
|
||||||
|
|
||||||
s.Emit(&sw.Nbody)
|
s.Emit(sw.PtrBody())
|
||||||
sw.Nbody.Append(defaultGoto)
|
sw.PtrBody().Append(defaultGoto)
|
||||||
sw.Nbody.AppendNodes(&body)
|
sw.PtrBody().AppendNodes(&body)
|
||||||
|
|
||||||
walkstmtlist(sw.Nbody.Slice())
|
walkstmtlist(sw.Body().Slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
// A typeSwitch walks a type switch.
|
// 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)
|
// cv, ok = iface.(type)
|
||||||
as := ir.NodAt(pos, ir.OAS2, nil, nil)
|
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 := ir.NodAt(pos, ir.ODOTTYPE, s.facename, nil)
|
||||||
dot.Type = typ // iface.(type)
|
dot.SetType(typ) // iface.(type)
|
||||||
as.Rlist.Set1(dot)
|
as.PtrRlist().Set1(dot)
|
||||||
as = typecheck(as, ctxStmt)
|
as = typecheck(as, ctxStmt)
|
||||||
as = walkexpr(as, &body)
|
as = walkexpr(as, &body)
|
||||||
body.Append(as)
|
body.Append(as)
|
||||||
|
|
||||||
// if ok { goto label }
|
// if ok { goto label }
|
||||||
nif := ir.NodAt(pos, ir.OIF, nil, nil)
|
nif := ir.NodAt(pos, ir.OIF, nil, nil)
|
||||||
nif.Left = s.okname
|
nif.SetLeft(s.okname)
|
||||||
nif.Nbody.Set1(jmp)
|
nif.PtrBody().Set1(jmp)
|
||||||
body.Append(nif)
|
body.Append(nif)
|
||||||
|
|
||||||
if !typ.IsInterface() {
|
if !typ.IsInterface() {
|
||||||
|
|
@ -710,8 +710,8 @@ func (s *typeSwitch) flush() {
|
||||||
// TODO(mdempsky): Omit hash equality check if
|
// TODO(mdempsky): Omit hash equality check if
|
||||||
// there's only one type.
|
// there's only one type.
|
||||||
c := cc[i]
|
c := cc[i]
|
||||||
nif.Left = ir.Nod(ir.OEQ, s.hashname, nodintconst(int64(c.hash)))
|
nif.SetLeft(ir.Nod(ir.OEQ, s.hashname, nodintconst(int64(c.hash))))
|
||||||
nif.Nbody.AppendNodes(&c.body)
|
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)
|
nif := ir.Nod(ir.OIF, nil, nil)
|
||||||
leaf(i, nif)
|
leaf(i, nif)
|
||||||
base.Pos = base.Pos.WithNotStmt()
|
base.Pos = base.Pos.WithNotStmt()
|
||||||
nif.Left = typecheck(nif.Left, ctxExpr)
|
nif.SetLeft(typecheck(nif.Left(), ctxExpr))
|
||||||
nif.Left = defaultlit(nif.Left, nil)
|
nif.SetLeft(defaultlit(nif.Left(), nil))
|
||||||
out.Append(nif)
|
out.Append(nif)
|
||||||
out = &nif.Rlist
|
out = nif.PtrRlist()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
half := lo + n/2
|
half := lo + n/2
|
||||||
nif := ir.Nod(ir.OIF, nil, nil)
|
nif := ir.Nod(ir.OIF, nil, nil)
|
||||||
nif.Left = less(half)
|
nif.SetLeft(less(half))
|
||||||
base.Pos = base.Pos.WithNotStmt()
|
base.Pos = base.Pos.WithNotStmt()
|
||||||
nif.Left = typecheck(nif.Left, ctxExpr)
|
nif.SetLeft(typecheck(nif.Left(), ctxExpr))
|
||||||
nif.Left = defaultlit(nif.Left, nil)
|
nif.SetLeft(defaultlit(nif.Left(), nil))
|
||||||
do(lo, half, &nif.Nbody)
|
do(lo, half, nif.PtrBody())
|
||||||
do(half, hi, &nif.Rlist)
|
do(half, hi, nif.PtrRlist())
|
||||||
out.Append(nif)
|
out.Append(nif)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -110,7 +110,7 @@ func lexinit() {
|
||||||
types.Types[etype] = t
|
types.Types[etype] = t
|
||||||
}
|
}
|
||||||
s2.Def = ir.AsTypesNode(typenod(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 {
|
for _, s := range &builtinFuncs {
|
||||||
|
|
@ -131,39 +131,39 @@ func lexinit() {
|
||||||
|
|
||||||
s := ir.BuiltinPkg.Lookup("true")
|
s := ir.BuiltinPkg.Lookup("true")
|
||||||
s.Def = ir.AsTypesNode(nodbool(true))
|
s.Def = ir.AsTypesNode(nodbool(true))
|
||||||
ir.AsNode(s.Def).Sym = lookup("true")
|
ir.AsNode(s.Def).SetSym(lookup("true"))
|
||||||
ir.AsNode(s.Def).Name = new(ir.Name)
|
ir.AsNode(s.Def).SetName(new(ir.Name))
|
||||||
ir.AsNode(s.Def).Type = types.UntypedBool
|
ir.AsNode(s.Def).SetType(types.UntypedBool)
|
||||||
|
|
||||||
s = ir.BuiltinPkg.Lookup("false")
|
s = ir.BuiltinPkg.Lookup("false")
|
||||||
s.Def = ir.AsTypesNode(nodbool(false))
|
s.Def = ir.AsTypesNode(nodbool(false))
|
||||||
ir.AsNode(s.Def).Sym = lookup("false")
|
ir.AsNode(s.Def).SetSym(lookup("false"))
|
||||||
ir.AsNode(s.Def).Name = new(ir.Name)
|
ir.AsNode(s.Def).SetName(new(ir.Name))
|
||||||
ir.AsNode(s.Def).Type = types.UntypedBool
|
ir.AsNode(s.Def).SetType(types.UntypedBool)
|
||||||
|
|
||||||
s = lookup("_")
|
s = lookup("_")
|
||||||
s.Block = -100
|
s.Block = -100
|
||||||
s.Def = ir.AsTypesNode(NewName(s))
|
s.Def = ir.AsTypesNode(NewName(s))
|
||||||
types.Types[types.TBLANK] = types.New(types.TBLANK)
|
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)
|
ir.BlankNode = ir.AsNode(s.Def)
|
||||||
|
|
||||||
s = ir.BuiltinPkg.Lookup("_")
|
s = ir.BuiltinPkg.Lookup("_")
|
||||||
s.Block = -100
|
s.Block = -100
|
||||||
s.Def = ir.AsTypesNode(NewName(s))
|
s.Def = ir.AsTypesNode(NewName(s))
|
||||||
types.Types[types.TBLANK] = types.New(types.TBLANK)
|
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)
|
types.Types[types.TNIL] = types.New(types.TNIL)
|
||||||
s = ir.BuiltinPkg.Lookup("nil")
|
s = ir.BuiltinPkg.Lookup("nil")
|
||||||
s.Def = ir.AsTypesNode(nodnil())
|
s.Def = ir.AsTypesNode(nodnil())
|
||||||
ir.AsNode(s.Def).Sym = s
|
ir.AsNode(s.Def).SetSym(s)
|
||||||
ir.AsNode(s.Def).Name = new(ir.Name)
|
ir.AsNode(s.Def).SetName(new(ir.Name))
|
||||||
|
|
||||||
s = ir.BuiltinPkg.Lookup("iota")
|
s = ir.BuiltinPkg.Lookup("iota")
|
||||||
s.Def = ir.AsTypesNode(ir.Nod(ir.OIOTA, nil, nil))
|
s.Def = ir.AsTypesNode(ir.Nod(ir.OIOTA, nil, nil))
|
||||||
ir.AsNode(s.Def).Sym = s
|
ir.AsNode(s.Def).SetSym(s)
|
||||||
ir.AsNode(s.Def).Name = new(ir.Name)
|
ir.AsNode(s.Def).SetName(new(ir.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
func typeinit() {
|
func typeinit() {
|
||||||
|
|
@ -182,7 +182,7 @@ func typeinit() {
|
||||||
types.Types[types.TUNSAFEPTR] = t
|
types.Types[types.TUNSAFEPTR] = t
|
||||||
t.Sym = unsafepkg.Lookup("Pointer")
|
t.Sym = unsafepkg.Lookup("Pointer")
|
||||||
t.Sym.Def = ir.AsTypesNode(typenod(t))
|
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])
|
dowidth(types.Types[types.TUNSAFEPTR])
|
||||||
|
|
||||||
for et := types.TINT8; et <= types.TUINT64; et++ {
|
for et := types.TINT8; et <= types.TUINT64; et++ {
|
||||||
|
|
@ -359,7 +359,7 @@ func lexinit1() {
|
||||||
types.Bytetype = types.New(types.TUINT8)
|
types.Bytetype = types.New(types.TUINT8)
|
||||||
types.Bytetype.Sym = s
|
types.Bytetype.Sym = s
|
||||||
s.Def = ir.AsTypesNode(typenod(types.Bytetype))
|
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)
|
dowidth(types.Bytetype)
|
||||||
|
|
||||||
// rune alias
|
// rune alias
|
||||||
|
|
@ -367,7 +367,7 @@ func lexinit1() {
|
||||||
types.Runetype = types.New(types.TINT32)
|
types.Runetype = types.New(types.TINT32)
|
||||||
types.Runetype.Sym = s
|
types.Runetype.Sym = s
|
||||||
s.Def = ir.AsTypesNode(typenod(types.Runetype))
|
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)
|
dowidth(types.Runetype)
|
||||||
|
|
||||||
// backend-dependent builtin types (e.g. int).
|
// backend-dependent builtin types (e.g. int).
|
||||||
|
|
@ -385,7 +385,7 @@ func lexinit1() {
|
||||||
t.Sym = s1
|
t.Sym = s1
|
||||||
types.Types[s.etype] = t
|
types.Types[s.etype] = t
|
||||||
s1.Def = ir.AsTypesNode(typenod(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
|
s1.Origpkg = ir.BuiltinPkg
|
||||||
|
|
||||||
dowidth(t)
|
dowidth(t)
|
||||||
|
|
@ -412,7 +412,7 @@ func finishUniverse() {
|
||||||
}
|
}
|
||||||
|
|
||||||
nodfp = NewName(lookup(".fp"))
|
nodfp = NewName(lookup(".fp"))
|
||||||
nodfp.Type = types.Types[types.TINT32]
|
nodfp.SetType(types.Types[types.TINT32])
|
||||||
nodfp.SetClass(ir.PPARAM)
|
nodfp.SetClass(ir.PPARAM)
|
||||||
nodfp.Name.SetUsed(true)
|
nodfp.Name().SetUsed(true)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,23 +11,23 @@ import (
|
||||||
|
|
||||||
// evalunsafe evaluates a package unsafe operation and returns the result.
|
// evalunsafe evaluates a package unsafe operation and returns the result.
|
||||||
func evalunsafe(n *ir.Node) int64 {
|
func evalunsafe(n *ir.Node) int64 {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ir.OALIGNOF, ir.OSIZEOF:
|
case ir.OALIGNOF, ir.OSIZEOF:
|
||||||
n.Left = typecheck(n.Left, ctxExpr)
|
n.SetLeft(typecheck(n.Left(), ctxExpr))
|
||||||
n.Left = defaultlit(n.Left, nil)
|
n.SetLeft(defaultlit(n.Left(), nil))
|
||||||
tr := n.Left.Type
|
tr := n.Left().Type()
|
||||||
if tr == nil {
|
if tr == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
dowidth(tr)
|
dowidth(tr)
|
||||||
if n.Op == ir.OALIGNOF {
|
if n.Op() == ir.OALIGNOF {
|
||||||
return int64(tr.Align)
|
return int64(tr.Align)
|
||||||
}
|
}
|
||||||
return tr.Width
|
return tr.Width
|
||||||
|
|
||||||
case ir.OOFFSETOF:
|
case ir.OOFFSETOF:
|
||||||
// must be a selector.
|
// must be a selector.
|
||||||
if n.Left.Op != ir.OXDOT {
|
if n.Left().Op() != ir.OXDOT {
|
||||||
base.Errorf("invalid expression %v", n)
|
base.Errorf("invalid expression %v", n)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
@ -35,14 +35,14 @@ func evalunsafe(n *ir.Node) int64 {
|
||||||
// Remember base of selector to find it back after dot insertion.
|
// Remember base of selector to find it back after dot insertion.
|
||||||
// Since r->left may be mutated by typechecking, check it explicitly
|
// Since r->left may be mutated by typechecking, check it explicitly
|
||||||
// first to track it correctly.
|
// first to track it correctly.
|
||||||
n.Left.Left = typecheck(n.Left.Left, ctxExpr)
|
n.Left().SetLeft(typecheck(n.Left().Left(), ctxExpr))
|
||||||
sbase := n.Left.Left
|
sbase := n.Left().Left()
|
||||||
|
|
||||||
n.Left = typecheck(n.Left, ctxExpr)
|
n.SetLeft(typecheck(n.Left(), ctxExpr))
|
||||||
if n.Left.Type == nil {
|
if n.Left().Type() == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
switch n.Left.Op {
|
switch n.Left().Op() {
|
||||||
case ir.ODOT, ir.ODOTPTR:
|
case ir.ODOT, ir.ODOTPTR:
|
||||||
break
|
break
|
||||||
case ir.OCALLPART:
|
case ir.OCALLPART:
|
||||||
|
|
@ -55,27 +55,27 @@ func evalunsafe(n *ir.Node) int64 {
|
||||||
|
|
||||||
// Sum offsets for dots until we reach sbase.
|
// Sum offsets for dots until we reach sbase.
|
||||||
var v int64
|
var v int64
|
||||||
for r := n.Left; r != sbase; r = r.Left {
|
for r := n.Left(); r != sbase; r = r.Left() {
|
||||||
switch r.Op {
|
switch r.Op() {
|
||||||
case ir.ODOTPTR:
|
case ir.ODOTPTR:
|
||||||
// For Offsetof(s.f), s may itself be a pointer,
|
// For Offsetof(s.f), s may itself be a pointer,
|
||||||
// but accessing f must not otherwise involve
|
// but accessing f must not otherwise involve
|
||||||
// indirection via embedded pointer types.
|
// indirection via embedded pointer types.
|
||||||
if r.Left != sbase {
|
if r.Left() != sbase {
|
||||||
base.Errorf("invalid expression %v: selector implies indirection of embedded %v", n, r.Left)
|
base.Errorf("invalid expression %v: selector implies indirection of embedded %v", n, r.Left())
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case ir.ODOT:
|
case ir.ODOT:
|
||||||
v += r.Xoffset
|
v += r.Offset()
|
||||||
default:
|
default:
|
||||||
ir.Dump("unsafenmagic", n.Left)
|
ir.Dump("unsafenmagic", n.Left())
|
||||||
base.Fatalf("impossible %#v node after dot insertion", r.Op)
|
base.Fatalf("impossible %#v node after dot insertion", r.Op())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Fatalf("unexpected op %v", n.Op)
|
base.Fatalf("unexpected op %v", n.Op())
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -205,7 +205,7 @@ func (p *dumper) dump(x reflect.Value, depth int) {
|
||||||
isNode := false
|
isNode := false
|
||||||
if n, ok := x.Interface().(Node); ok {
|
if n, ok := x.Interface().(Node); ok {
|
||||||
isNode = true
|
isNode = true
|
||||||
p.printf("%s %s {", n.Op.String(), p.addr(x))
|
p.printf("%s %s {", n.op.String(), p.addr(x))
|
||||||
} else {
|
} else {
|
||||||
p.printf("%s {", typ)
|
p.printf("%s {", typ)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -351,28 +351,28 @@ func jconvFmt(n *Node, s fmt.State, flag FmtFlag) {
|
||||||
if base.Debug.DumpPtrs != 0 {
|
if base.Debug.DumpPtrs != 0 {
|
||||||
fmt.Fprintf(s, " p(%p)", n)
|
fmt.Fprintf(s, " p(%p)", n)
|
||||||
}
|
}
|
||||||
if !short && n.Name != nil && n.Name.Vargen != 0 {
|
if !short && n.Name() != nil && n.Name().Vargen != 0 {
|
||||||
fmt.Fprintf(s, " g(%d)", n.Name.Vargen)
|
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
|
// 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 := ""
|
pfx := ""
|
||||||
switch n.Pos.IsStmt() {
|
switch n.Pos().IsStmt() {
|
||||||
case src.PosNotStmt:
|
case src.PosNotStmt:
|
||||||
pfx = "_" // "-" would be confusing
|
pfx = "_" // "-" would be confusing
|
||||||
case src.PosIsStmt:
|
case src.PosIsStmt:
|
||||||
pfx = "+"
|
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 {
|
if !short && n.Offset() != types.BADWIDTH {
|
||||||
fmt.Fprintf(s, " x(%d)", n.Xoffset)
|
fmt.Fprintf(s, " x(%d)", n.Offset())
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Class() != 0 {
|
if n.Class() != 0 {
|
||||||
|
|
@ -405,20 +405,20 @@ func jconvFmt(n *Node, s fmt.State, flag FmtFlag) {
|
||||||
fmt.Fprintf(s, " embedded")
|
fmt.Fprintf(s, " embedded")
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Op == ONAME {
|
if n.Op() == ONAME {
|
||||||
if n.Name.Addrtaken() {
|
if n.Name().Addrtaken() {
|
||||||
fmt.Fprint(s, " addrtaken")
|
fmt.Fprint(s, " addrtaken")
|
||||||
}
|
}
|
||||||
if n.Name.Assigned() {
|
if n.Name().Assigned() {
|
||||||
fmt.Fprint(s, " assigned")
|
fmt.Fprint(s, " assigned")
|
||||||
}
|
}
|
||||||
if n.Name.IsClosureVar() {
|
if n.Name().IsClosureVar() {
|
||||||
fmt.Fprint(s, " closurevar")
|
fmt.Fprint(s, " closurevar")
|
||||||
}
|
}
|
||||||
if n.Name.Captured() {
|
if n.Name().Captured() {
|
||||||
fmt.Fprint(s, " captured")
|
fmt.Fprint(s, " captured")
|
||||||
}
|
}
|
||||||
if n.Name.IsOutputParamHeapAddr() {
|
if n.Name().IsOutputParamHeapAddr() {
|
||||||
fmt.Fprint(s, " outputparamheapaddr")
|
fmt.Fprint(s, " outputparamheapaddr")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -433,7 +433,7 @@ func jconvFmt(n *Node, s fmt.State, flag FmtFlag) {
|
||||||
fmt.Fprint(s, " hascall")
|
fmt.Fprint(s, " hascall")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !short && n.Name != nil && n.Name.Used() {
|
if !short && n.Name() != nil && n.Name().Used() {
|
||||||
fmt.Fprint(s, " used")
|
fmt.Fprint(s, " used")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -899,31 +899,31 @@ func stmtFmt(n *Node, s fmt.State, mode FmtMode) {
|
||||||
// block starting with the init statements.
|
// block starting with the init statements.
|
||||||
|
|
||||||
// if we can just say "for" n->ninit; ... then do so
|
// 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
|
// 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
|
// 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 {
|
if extrablock {
|
||||||
fmt.Fprint(s, "{")
|
fmt.Fprint(s, "{")
|
||||||
}
|
}
|
||||||
|
|
||||||
if complexinit {
|
if complexinit {
|
||||||
mode.Fprintf(s, " %v; ", n.Ninit)
|
mode.Fprintf(s, " %v; ", n.Init())
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ODCL:
|
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:
|
case ODCLFIELD:
|
||||||
if n.Sym != nil {
|
if n.Sym() != nil {
|
||||||
mode.Fprintf(s, "%v %v", n.Sym, n.Left)
|
mode.Fprintf(s, "%v %v", n.Sym(), n.Left())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%v", n.Left)
|
mode.Fprintf(s, "%v", n.Left())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't export "v = <N>" initializing statements, hope they're always
|
// Don't export "v = <N>" initializing statements, hope they're always
|
||||||
|
|
@ -931,61 +931,61 @@ func stmtFmt(n *Node, s fmt.State, mode FmtMode) {
|
||||||
// the "v = <N>" again.
|
// the "v = <N>" again.
|
||||||
case OAS:
|
case OAS:
|
||||||
if n.Colas() && !complexinit {
|
if n.Colas() && !complexinit {
|
||||||
mode.Fprintf(s, "%v := %v", n.Left, n.Right)
|
mode.Fprintf(s, "%v := %v", n.Left(), n.Right())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%v = %v", n.Left, n.Right)
|
mode.Fprintf(s, "%v = %v", n.Left(), n.Right())
|
||||||
}
|
}
|
||||||
|
|
||||||
case OASOP:
|
case OASOP:
|
||||||
if n.Implicit() {
|
if n.Implicit() {
|
||||||
if n.SubOp() == OADD {
|
if n.SubOp() == OADD {
|
||||||
mode.Fprintf(s, "%v++", n.Left)
|
mode.Fprintf(s, "%v++", n.Left())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%v--", n.Left)
|
mode.Fprintf(s, "%v--", n.Left())
|
||||||
}
|
}
|
||||||
break
|
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:
|
case OAS2:
|
||||||
if n.Colas() && !complexinit {
|
if n.Colas() && !complexinit {
|
||||||
mode.Fprintf(s, "%.v := %.v", n.List, n.Rlist)
|
mode.Fprintf(s, "%.v := %.v", n.List(), n.Rlist())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
|
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:
|
case ORETURN:
|
||||||
mode.Fprintf(s, "return %.v", n.List)
|
mode.Fprintf(s, "return %.v", n.List())
|
||||||
|
|
||||||
case ORETJMP:
|
case ORETJMP:
|
||||||
mode.Fprintf(s, "retjmp %v", n.Sym)
|
mode.Fprintf(s, "retjmp %v", n.Sym())
|
||||||
|
|
||||||
case OINLMARK:
|
case OINLMARK:
|
||||||
mode.Fprintf(s, "inlmark %d", n.Xoffset)
|
mode.Fprintf(s, "inlmark %d", n.Offset())
|
||||||
|
|
||||||
case OGO:
|
case OGO:
|
||||||
mode.Fprintf(s, "go %v", n.Left)
|
mode.Fprintf(s, "go %v", n.Left())
|
||||||
|
|
||||||
case ODEFER:
|
case ODEFER:
|
||||||
mode.Fprintf(s, "defer %v", n.Left)
|
mode.Fprintf(s, "defer %v", n.Left())
|
||||||
|
|
||||||
case OIF:
|
case OIF:
|
||||||
if simpleinit {
|
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 {
|
} 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 {
|
if n.Rlist().Len() != 0 {
|
||||||
mode.Fprintf(s, " else { %v }", n.Rlist)
|
mode.Fprintf(s, " else { %v }", n.Rlist())
|
||||||
}
|
}
|
||||||
|
|
||||||
case OFOR, OFORUNTIL:
|
case OFOR, OFORUNTIL:
|
||||||
opname := "for"
|
opname := "for"
|
||||||
if n.Op == OFORUNTIL {
|
if n.Op() == OFORUNTIL {
|
||||||
opname = "foruntil"
|
opname = "foruntil"
|
||||||
}
|
}
|
||||||
if mode == FErr { // TODO maybe only if FmtShort, same below
|
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)
|
fmt.Fprint(s, opname)
|
||||||
if simpleinit {
|
if simpleinit {
|
||||||
mode.Fprintf(s, " %v;", n.Ninit.First())
|
mode.Fprintf(s, " %v;", n.Init().First())
|
||||||
} else if n.Right != nil {
|
} else if n.Right() != nil {
|
||||||
fmt.Fprint(s, " ;")
|
fmt.Fprint(s, " ;")
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
mode.Fprintf(s, " %v", n.Left)
|
mode.Fprintf(s, " %v", n.Left())
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Right != nil {
|
if n.Right() != nil {
|
||||||
mode.Fprintf(s, "; %v", n.Right)
|
mode.Fprintf(s, "; %v", n.Right())
|
||||||
} else if simpleinit {
|
} else if simpleinit {
|
||||||
fmt.Fprint(s, ";")
|
fmt.Fprint(s, ";")
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Op == OFORUNTIL && n.List.Len() != 0 {
|
if n.Op() == OFORUNTIL && n.List().Len() != 0 {
|
||||||
mode.Fprintf(s, "; %v", n.List)
|
mode.Fprintf(s, "; %v", n.List())
|
||||||
}
|
}
|
||||||
|
|
||||||
mode.Fprintf(s, " { %v }", n.Nbody)
|
mode.Fprintf(s, " { %v }", n.Body())
|
||||||
|
|
||||||
case ORANGE:
|
case ORANGE:
|
||||||
if mode == FErr {
|
if mode == FErr {
|
||||||
|
|
@ -1022,49 +1022,49 @@ func stmtFmt(n *Node, s fmt.State, mode FmtMode) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.List.Len() == 0 {
|
if n.List().Len() == 0 {
|
||||||
mode.Fprintf(s, "for range %v { %v }", n.Right, n.Nbody)
|
mode.Fprintf(s, "for range %v { %v }", n.Right(), n.Body())
|
||||||
break
|
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:
|
case OSELECT, OSWITCH:
|
||||||
if mode == FErr {
|
if mode == FErr {
|
||||||
mode.Fprintf(s, "%v statement", n.Op)
|
mode.Fprintf(s, "%v statement", n.Op())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
mode.Fprintf(s, "%#v", n.Op)
|
mode.Fprintf(s, "%#v", n.Op())
|
||||||
if simpleinit {
|
if simpleinit {
|
||||||
mode.Fprintf(s, " %v;", n.Ninit.First())
|
mode.Fprintf(s, " %v;", n.Init().First())
|
||||||
}
|
}
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
mode.Fprintf(s, " %v ", n.Left)
|
mode.Fprintf(s, " %v ", n.Left())
|
||||||
}
|
}
|
||||||
|
|
||||||
mode.Fprintf(s, " { %v }", n.List)
|
mode.Fprintf(s, " { %v }", n.List())
|
||||||
|
|
||||||
case OCASE:
|
case OCASE:
|
||||||
if n.List.Len() != 0 {
|
if n.List().Len() != 0 {
|
||||||
mode.Fprintf(s, "case %.v", n.List)
|
mode.Fprintf(s, "case %.v", n.List())
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprint(s, "default")
|
fmt.Fprint(s, "default")
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, ": %v", n.Nbody)
|
mode.Fprintf(s, ": %v", n.Body())
|
||||||
|
|
||||||
case OBREAK, OCONTINUE, OGOTO, OFALL:
|
case OBREAK, OCONTINUE, OGOTO, OFALL:
|
||||||
if n.Sym != nil {
|
if n.Sym() != nil {
|
||||||
mode.Fprintf(s, "%#v %v", n.Op, n.Sym)
|
mode.Fprintf(s, "%#v %v", n.Op(), n.Sym())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%#v", n.Op)
|
mode.Fprintf(s, "%#v", n.Op())
|
||||||
}
|
}
|
||||||
|
|
||||||
case OEMPTY:
|
case OEMPTY:
|
||||||
break
|
break
|
||||||
|
|
||||||
case OLABEL:
|
case OLABEL:
|
||||||
mode.Fprintf(s, "%v: ", n.Sym)
|
mode.Fprintf(s, "%v: ", n.Sym())
|
||||||
}
|
}
|
||||||
|
|
||||||
if extrablock {
|
if extrablock {
|
||||||
|
|
@ -1193,8 +1193,8 @@ var OpPrec = []int{
|
||||||
}
|
}
|
||||||
|
|
||||||
func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) {
|
func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
for n != nil && n.Implicit() && (n.Op == ODEREF || n.Op == OADDR) {
|
for n != nil && n.Implicit() && (n.Op() == ODEREF || n.Op() == OADDR) {
|
||||||
n = n.Left
|
n = n.Left()
|
||||||
}
|
}
|
||||||
|
|
||||||
if n == nil {
|
if n == nil {
|
||||||
|
|
@ -1202,8 +1202,8 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nprec := OpPrec[n.Op]
|
nprec := OpPrec[n.Op()]
|
||||||
if n.Op == OTYPE && n.Sym != nil {
|
if n.Op() == OTYPE && n.Sym() != nil {
|
||||||
nprec = 8
|
nprec = 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1212,38 +1212,38 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case OPAREN:
|
case OPAREN:
|
||||||
mode.Fprintf(s, "(%v)", n.Left)
|
mode.Fprintf(s, "(%v)", n.Left())
|
||||||
|
|
||||||
case ONIL:
|
case ONIL:
|
||||||
fmt.Fprint(s, "nil")
|
fmt.Fprint(s, "nil")
|
||||||
|
|
||||||
case OLITERAL: // this is a bit of a mess
|
case OLITERAL: // this is a bit of a mess
|
||||||
if mode == FErr {
|
if mode == FErr {
|
||||||
if n.Orig != nil && n.Orig != n {
|
if n.Orig() != nil && n.Orig() != n {
|
||||||
exprFmt(n.Orig, s, prec, mode)
|
exprFmt(n.Orig(), s, prec, mode)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Sym != nil {
|
if n.Sym() != nil {
|
||||||
fmt.Fprint(s, smodeString(n.Sym, mode))
|
fmt.Fprint(s, smodeString(n.Sym(), mode))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
needUnparen := false
|
needUnparen := false
|
||||||
if n.Type != nil && !n.Type.IsUntyped() {
|
if n.Type() != nil && !n.Type().IsUntyped() {
|
||||||
// Need parens when type begins with what might
|
// Need parens when type begins with what might
|
||||||
// be misinterpreted as a unary operator: * or <-.
|
// be misinterpreted as a unary operator: * or <-.
|
||||||
if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == types.Crecv) {
|
if n.Type().IsPtr() || (n.Type().IsChan() && n.Type().ChanDir() == types.Crecv) {
|
||||||
mode.Fprintf(s, "(%v)(", n.Type)
|
mode.Fprintf(s, "(%v)(", n.Type())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%v(", n.Type)
|
mode.Fprintf(s, "%v(", n.Type())
|
||||||
}
|
}
|
||||||
needUnparen = true
|
needUnparen = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Type == types.UntypedRune {
|
if n.Type() == types.UntypedRune {
|
||||||
switch x, ok := constant.Int64Val(n.Val()); {
|
switch x, ok := constant.Int64Val(n.Val()); {
|
||||||
case !ok:
|
case !ok:
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
@ -1270,44 +1270,44 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
case ONAME:
|
case ONAME:
|
||||||
// Special case: name used as local variable in export.
|
// Special case: name used as local variable in export.
|
||||||
// _ becomes ~b%d internally; print as _ for 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, "_")
|
fmt.Fprint(s, "_")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case OPACK, ONONAME, OMETHEXPR:
|
case OPACK, ONONAME, OMETHEXPR:
|
||||||
fmt.Fprint(s, smodeString(n.Sym, mode))
|
fmt.Fprint(s, smodeString(n.Sym(), mode))
|
||||||
|
|
||||||
case OTYPE:
|
case OTYPE:
|
||||||
if n.Type == nil && n.Sym != nil {
|
if n.Type() == nil && n.Sym() != nil {
|
||||||
fmt.Fprint(s, smodeString(n.Sym, mode))
|
fmt.Fprint(s, smodeString(n.Sym(), mode))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "%v", n.Type)
|
mode.Fprintf(s, "%v", n.Type())
|
||||||
|
|
||||||
case OTARRAY:
|
case OTARRAY:
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
mode.Fprintf(s, "[%v]%v", n.Left, n.Right)
|
mode.Fprintf(s, "[%v]%v", n.Left(), n.Right())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "[]%v", n.Right) // happens before typecheck
|
mode.Fprintf(s, "[]%v", n.Right()) // happens before typecheck
|
||||||
|
|
||||||
case OTMAP:
|
case OTMAP:
|
||||||
mode.Fprintf(s, "map[%v]%v", n.Left, n.Right)
|
mode.Fprintf(s, "map[%v]%v", n.Left(), n.Right())
|
||||||
|
|
||||||
case OTCHAN:
|
case OTCHAN:
|
||||||
switch n.TChanDir() {
|
switch n.TChanDir() {
|
||||||
case types.Crecv:
|
case types.Crecv:
|
||||||
mode.Fprintf(s, "<-chan %v", n.Left)
|
mode.Fprintf(s, "<-chan %v", n.Left())
|
||||||
|
|
||||||
case types.Csend:
|
case types.Csend:
|
||||||
mode.Fprintf(s, "chan<- %v", n.Left)
|
mode.Fprintf(s, "chan<- %v", n.Left())
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if n.Left != nil && n.Left.Op == OTCHAN && n.Left.Sym == nil && n.Left.TChanDir() == types.Crecv {
|
if n.Left() != nil && n.Left().Op() == OTCHAN && n.Left().Sym() == nil && n.Left().TChanDir() == types.Crecv {
|
||||||
mode.Fprintf(s, "chan (%v)", n.Left)
|
mode.Fprintf(s, "chan (%v)", n.Left())
|
||||||
} else {
|
} 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")
|
fmt.Fprint(s, "func literal")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Nbody.Len() != 0 {
|
if n.Body().Len() != 0 {
|
||||||
mode.Fprintf(s, "%v { %v }", n.Type, n.Nbody)
|
mode.Fprintf(s, "%v { %v }", n.Type(), n.Body())
|
||||||
return
|
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:
|
case OCOMPLIT:
|
||||||
if mode == FErr {
|
if mode == FErr {
|
||||||
|
|
@ -1337,75 +1337,75 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
mode.Fprintf(s, "... argument")
|
mode.Fprintf(s, "... argument")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Right != nil {
|
if n.Right() != nil {
|
||||||
mode.Fprintf(s, "%v{%s}", n.Right, ellipsisIf(n.List.Len() != 0))
|
mode.Fprintf(s, "%v{%s}", n.Right(), ellipsisIf(n.List().Len() != 0))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprint(s, "composite literal")
|
fmt.Fprint(s, "composite literal")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "(%v{ %.v })", n.Right, n.List)
|
mode.Fprintf(s, "(%v{ %.v })", n.Right(), n.List())
|
||||||
|
|
||||||
case OPTRLIT:
|
case OPTRLIT:
|
||||||
mode.Fprintf(s, "&%v", n.Left)
|
mode.Fprintf(s, "&%v", n.Left())
|
||||||
|
|
||||||
case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
|
case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
|
||||||
if mode == FErr {
|
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
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "(%v{ %.v })", n.Type, n.List)
|
mode.Fprintf(s, "(%v{ %.v })", n.Type(), n.List())
|
||||||
|
|
||||||
case OKEY:
|
case OKEY:
|
||||||
if n.Left != nil && n.Right != nil {
|
if n.Left() != nil && n.Right() != nil {
|
||||||
mode.Fprintf(s, "%v:%v", n.Left, n.Right)
|
mode.Fprintf(s, "%v:%v", n.Left(), n.Right())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Left == nil && n.Right != nil {
|
if n.Left() == nil && n.Right() != nil {
|
||||||
mode.Fprintf(s, ":%v", n.Right)
|
mode.Fprintf(s, ":%v", n.Right())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Left != nil && n.Right == nil {
|
if n.Left() != nil && n.Right() == nil {
|
||||||
mode.Fprintf(s, "%v:", n.Left)
|
mode.Fprintf(s, "%v:", n.Left())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Fprint(s, ":")
|
fmt.Fprint(s, ":")
|
||||||
|
|
||||||
case OSTRUCTKEY:
|
case OSTRUCTKEY:
|
||||||
mode.Fprintf(s, "%v:%v", n.Sym, n.Left)
|
mode.Fprintf(s, "%v:%v", n.Sym(), n.Left())
|
||||||
|
|
||||||
case OCALLPART:
|
case OCALLPART:
|
||||||
exprFmt(n.Left, s, nprec, mode)
|
exprFmt(n.Left(), s, nprec, mode)
|
||||||
if n.Right == nil || n.Right.Sym == nil {
|
if n.Right() == nil || n.Right().Sym() == nil {
|
||||||
fmt.Fprint(s, ".<nil>")
|
fmt.Fprint(s, ".<nil>")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, ".%0S", n.Right.Sym)
|
mode.Fprintf(s, ".%0S", n.Right().Sym())
|
||||||
|
|
||||||
case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
|
case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
|
||||||
exprFmt(n.Left, s, nprec, mode)
|
exprFmt(n.Left(), s, nprec, mode)
|
||||||
if n.Sym == nil {
|
if n.Sym() == nil {
|
||||||
fmt.Fprint(s, ".<nil>")
|
fmt.Fprint(s, ".<nil>")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, ".%0S", n.Sym)
|
mode.Fprintf(s, ".%0S", n.Sym())
|
||||||
|
|
||||||
case ODOTTYPE, ODOTTYPE2:
|
case ODOTTYPE, ODOTTYPE2:
|
||||||
exprFmt(n.Left, s, nprec, mode)
|
exprFmt(n.Left(), s, nprec, mode)
|
||||||
if n.Right != nil {
|
if n.Right() != nil {
|
||||||
mode.Fprintf(s, ".(%v)", n.Right)
|
mode.Fprintf(s, ".(%v)", n.Right())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, ".(%v)", n.Type)
|
mode.Fprintf(s, ".(%v)", n.Type())
|
||||||
|
|
||||||
case OINDEX, OINDEXMAP:
|
case OINDEX, OINDEXMAP:
|
||||||
exprFmt(n.Left, s, nprec, mode)
|
exprFmt(n.Left(), s, nprec, mode)
|
||||||
mode.Fprintf(s, "[%v]", n.Right)
|
mode.Fprintf(s, "[%v]", n.Right())
|
||||||
|
|
||||||
case OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
|
case OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
|
||||||
exprFmt(n.Left, s, nprec, mode)
|
exprFmt(n.Left(), s, nprec, mode)
|
||||||
fmt.Fprint(s, "[")
|
fmt.Fprint(s, "[")
|
||||||
low, high, max := n.SliceBounds()
|
low, high, max := n.SliceBounds()
|
||||||
if low != nil {
|
if low != nil {
|
||||||
|
|
@ -1415,7 +1415,7 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
if high != nil {
|
if high != nil {
|
||||||
fmt.Fprint(s, modeString(high, mode))
|
fmt.Fprint(s, modeString(high, mode))
|
||||||
}
|
}
|
||||||
if n.Op.IsSlice3() {
|
if n.Op().IsSlice3() {
|
||||||
fmt.Fprint(s, ":")
|
fmt.Fprint(s, ":")
|
||||||
if max != nil {
|
if max != nil {
|
||||||
fmt.Fprint(s, modeString(max, mode))
|
fmt.Fprint(s, modeString(max, mode))
|
||||||
|
|
@ -1424,16 +1424,16 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
fmt.Fprint(s, "]")
|
fmt.Fprint(s, "]")
|
||||||
|
|
||||||
case OSLICEHEADER:
|
case OSLICEHEADER:
|
||||||
if n.List.Len() != 2 {
|
if n.List().Len() != 2 {
|
||||||
base.Fatalf("bad OSLICEHEADER list length %d", n.List.Len())
|
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:
|
case OCOMPLEX, OCOPY:
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
mode.Fprintf(s, "%#v(%v, %v)", n.Op, n.Left, n.Right)
|
mode.Fprintf(s, "%#v(%v, %v)", n.Op(), n.Left(), n.Right())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%#v(%.v)", n.Op, n.List)
|
mode.Fprintf(s, "%#v(%.v)", n.Op(), n.List())
|
||||||
}
|
}
|
||||||
|
|
||||||
case OCONV,
|
case OCONV,
|
||||||
|
|
@ -1444,15 +1444,15 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
OSTR2BYTES,
|
OSTR2BYTES,
|
||||||
OSTR2RUNES,
|
OSTR2RUNES,
|
||||||
ORUNESTR:
|
ORUNESTR:
|
||||||
if n.Type == nil || n.Type.Sym == nil {
|
if n.Type() == nil || n.Type().Sym == nil {
|
||||||
mode.Fprintf(s, "(%v)", n.Type)
|
mode.Fprintf(s, "(%v)", n.Type())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%v", n.Type)
|
mode.Fprintf(s, "%v", n.Type())
|
||||||
}
|
}
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
mode.Fprintf(s, "(%v)", n.Left)
|
mode.Fprintf(s, "(%v)", n.Left())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "(%.v)", n.List)
|
mode.Fprintf(s, "(%.v)", n.List())
|
||||||
}
|
}
|
||||||
|
|
||||||
case OREAL,
|
case OREAL,
|
||||||
|
|
@ -1471,49 +1471,49 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
OSIZEOF,
|
OSIZEOF,
|
||||||
OPRINT,
|
OPRINT,
|
||||||
OPRINTN:
|
OPRINTN:
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
mode.Fprintf(s, "%#v(%v)", n.Op, n.Left)
|
mode.Fprintf(s, "%#v(%v)", n.Op(), n.Left())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.IsDDD() {
|
if n.IsDDD() {
|
||||||
mode.Fprintf(s, "%#v(%.v...)", n.Op, n.List)
|
mode.Fprintf(s, "%#v(%.v...)", n.Op(), n.List())
|
||||||
return
|
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:
|
case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG:
|
||||||
exprFmt(n.Left, s, nprec, mode)
|
exprFmt(n.Left(), s, nprec, mode)
|
||||||
if n.IsDDD() {
|
if n.IsDDD() {
|
||||||
mode.Fprintf(s, "(%.v...)", n.List)
|
mode.Fprintf(s, "(%.v...)", n.List())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "(%.v)", n.List)
|
mode.Fprintf(s, "(%.v)", n.List())
|
||||||
|
|
||||||
case OMAKEMAP, OMAKECHAN, OMAKESLICE:
|
case OMAKEMAP, OMAKECHAN, OMAKESLICE:
|
||||||
if n.List.Len() != 0 { // pre-typecheck
|
if n.List().Len() != 0 { // pre-typecheck
|
||||||
mode.Fprintf(s, "make(%v, %.v)", n.Type, n.List)
|
mode.Fprintf(s, "make(%v, %.v)", n.Type(), n.List())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Right != nil {
|
if n.Right() != nil {
|
||||||
mode.Fprintf(s, "make(%v, %v, %v)", n.Type, n.Left, n.Right)
|
mode.Fprintf(s, "make(%v, %v, %v)", n.Type(), n.Left(), n.Right())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Left != nil && (n.Op == OMAKESLICE || !n.Left.Type.IsUntyped()) {
|
if n.Left() != nil && (n.Op() == OMAKESLICE || !n.Left().Type().IsUntyped()) {
|
||||||
mode.Fprintf(s, "make(%v, %v)", n.Type, n.Left)
|
mode.Fprintf(s, "make(%v, %v)", n.Type(), n.Left())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "make(%v)", n.Type)
|
mode.Fprintf(s, "make(%v)", n.Type())
|
||||||
|
|
||||||
case OMAKESLICECOPY:
|
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:
|
case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
|
||||||
// Unary
|
// Unary
|
||||||
mode.Fprintf(s, "%#v", n.Op)
|
mode.Fprintf(s, "%#v", n.Op())
|
||||||
if n.Left != nil && n.Left.Op == n.Op {
|
if n.Left() != nil && n.Left().Op() == n.Op() {
|
||||||
fmt.Fprint(s, " ")
|
fmt.Fprint(s, " ")
|
||||||
}
|
}
|
||||||
exprFmt(n.Left, s, nprec+1, mode)
|
exprFmt(n.Left(), s, nprec+1, mode)
|
||||||
|
|
||||||
// Binary
|
// Binary
|
||||||
case OADD,
|
case OADD,
|
||||||
|
|
@ -1536,12 +1536,12 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
OSEND,
|
OSEND,
|
||||||
OSUB,
|
OSUB,
|
||||||
OXOR:
|
OXOR:
|
||||||
exprFmt(n.Left, s, nprec, mode)
|
exprFmt(n.Left(), s, nprec, mode)
|
||||||
mode.Fprintf(s, " %#v ", n.Op)
|
mode.Fprintf(s, " %#v ", n.Op())
|
||||||
exprFmt(n.Right, s, nprec+1, mode)
|
exprFmt(n.Right(), s, nprec+1, mode)
|
||||||
|
|
||||||
case OADDSTR:
|
case OADDSTR:
|
||||||
for i, n1 := range n.List.Slice() {
|
for i, n1 := range n.List().Slice() {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
fmt.Fprint(s, " + ")
|
fmt.Fprint(s, " + ")
|
||||||
}
|
}
|
||||||
|
|
@ -1550,23 +1550,23 @@ func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
case ODDD:
|
case ODDD:
|
||||||
mode.Fprintf(s, "...")
|
mode.Fprintf(s, "...")
|
||||||
default:
|
default:
|
||||||
mode.Fprintf(s, "<node %v>", n.Op)
|
mode.Fprintf(s, "<node %v>", n.Op())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func nodeFmt(n *Node, s fmt.State, flag FmtFlag, mode FmtMode) {
|
func nodeFmt(n *Node, s fmt.State, flag FmtFlag, mode FmtMode) {
|
||||||
t := n.Type
|
t := n.Type()
|
||||||
|
|
||||||
// We almost always want the original.
|
// We almost always want the original.
|
||||||
// TODO(gri) Why the special case for OLITERAL?
|
// TODO(gri) Why the special case for OLITERAL?
|
||||||
if n.Op != OLITERAL && n.Orig != nil {
|
if n.Op() != OLITERAL && n.Orig() != nil {
|
||||||
n = n.Orig
|
n = n.Orig()
|
||||||
}
|
}
|
||||||
|
|
||||||
if flag&FmtLong != 0 && t != nil {
|
if flag&FmtLong != 0 && t != nil {
|
||||||
if t.Etype == types.TNIL {
|
if t.Etype == types.TNIL {
|
||||||
fmt.Fprint(s, "nil")
|
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)
|
mode.Fprintf(s, "%v value", t)
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%v (type %v)", n, t)
|
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.
|
// 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)
|
stmtFmt(n, s, mode)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1594,82 +1594,82 @@ func nodeDumpFmt(n *Node, s fmt.State, flag FmtFlag, mode FmtMode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Ninit.Len() != 0 {
|
if n.Init().Len() != 0 {
|
||||||
mode.Fprintf(s, "%v-init%v", n.Op, n.Ninit)
|
mode.Fprintf(s, "%v-init%v", n.Op(), n.Init())
|
||||||
indent(s)
|
indent(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
default:
|
default:
|
||||||
mode.Fprintf(s, "%v%j", n.Op, n)
|
mode.Fprintf(s, "%v%j", n.Op(), n)
|
||||||
|
|
||||||
case OLITERAL:
|
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:
|
case ONAME, ONONAME, OMETHEXPR:
|
||||||
if n.Sym != nil {
|
if n.Sym() != nil {
|
||||||
mode.Fprintf(s, "%v-%v%j", n.Op, n.Sym, n)
|
mode.Fprintf(s, "%v-%v%j", n.Op(), n.Sym(), n)
|
||||||
} else {
|
} 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)
|
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:
|
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:
|
case OTYPE:
|
||||||
mode.Fprintf(s, "%v %v%j type=%v", n.Op, n.Sym, n, n.Type)
|
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 {
|
if recur && n.Type() == nil && n.Name() != nil && n.Name().Param != nil && n.Name().Param.Ntype != nil {
|
||||||
indent(s)
|
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 {
|
if n.Op() == OCLOSURE && n.Func().Decl != nil && n.Func().Nname.Sym() != nil {
|
||||||
mode.Fprintf(s, " fnName %v", n.Func.Nname.Sym)
|
mode.Fprintf(s, " fnName %v", n.Func().Nname.Sym())
|
||||||
}
|
}
|
||||||
if n.Sym != nil && n.Op != ONAME {
|
if n.Sym() != nil && n.Op() != ONAME {
|
||||||
mode.Fprintf(s, " %v", n.Sym)
|
mode.Fprintf(s, " %v", n.Sym())
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Type != nil {
|
if n.Type() != nil {
|
||||||
mode.Fprintf(s, " %v", n.Type)
|
mode.Fprintf(s, " %v", n.Type())
|
||||||
}
|
}
|
||||||
|
|
||||||
if recur {
|
if recur {
|
||||||
if n.Left != nil {
|
if n.Left() != nil {
|
||||||
mode.Fprintf(s, "%v", n.Left)
|
mode.Fprintf(s, "%v", n.Left())
|
||||||
}
|
}
|
||||||
if n.Right != nil {
|
if n.Right() != nil {
|
||||||
mode.Fprintf(s, "%v", n.Right)
|
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)
|
indent(s)
|
||||||
// The function associated with a closure
|
// 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)
|
indent(s)
|
||||||
// The dcls for a func or closure
|
// 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)
|
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)
|
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)
|
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,
|
// Line returns n's position as a string. If n has been inlined,
|
||||||
// it uses the outermost position where n has been inlined.
|
// it uses the outermost position where n has been inlined.
|
||||||
func Line(n *Node) string {
|
func Line(n *Node) string {
|
||||||
return base.FmtPos(n.Pos)
|
return base.FmtPos(n.Pos())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,25 +26,25 @@ import (
|
||||||
type Node struct {
|
type Node struct {
|
||||||
// Tree structure.
|
// Tree structure.
|
||||||
// Generic recursive walks should follow these fields.
|
// Generic recursive walks should follow these fields.
|
||||||
Left *Node
|
left *Node
|
||||||
Right *Node
|
right *Node
|
||||||
Ninit Nodes
|
init Nodes
|
||||||
Nbody Nodes
|
body Nodes
|
||||||
List Nodes
|
list Nodes
|
||||||
Rlist Nodes
|
rlist Nodes
|
||||||
|
|
||||||
// most nodes
|
// most nodes
|
||||||
Type *types.Type
|
typ *types.Type
|
||||||
Orig *Node // original form, for printing, and tracking copies of ONAMEs
|
orig *Node // original form, for printing, and tracking copies of ONAMEs
|
||||||
|
|
||||||
// func
|
// func
|
||||||
Func *Func
|
fn *Func
|
||||||
|
|
||||||
// ONAME, OTYPE, OPACK, OLABEL, some OLITERAL
|
// ONAME, OTYPE, OPACK, OLABEL, some OLITERAL
|
||||||
Name *Name
|
name *Name
|
||||||
|
|
||||||
Sym *types.Sym // various
|
sym *types.Sym // various
|
||||||
E interface{} // Opt or Val, see methods below
|
e interface{} // Opt or Val, see methods below
|
||||||
|
|
||||||
// Various. Usually an offset into a struct. For example:
|
// Various. Usually an offset into a struct. For example:
|
||||||
// - ONAME nodes that refer to local variables use it to identify their stack frame position.
|
// - 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.
|
// - OINLMARK stores an index into the inlTree data structure.
|
||||||
// - OCLOSURE uses it to store ambient iota value, if any.
|
// - OCLOSURE uses it to store ambient iota value, if any.
|
||||||
// Possibly still more uses. If you find any, document them.
|
// Possibly still more uses. If you find any, document them.
|
||||||
Xoffset int64
|
offset int64
|
||||||
|
|
||||||
Pos src.XPos
|
pos src.XPos
|
||||||
|
|
||||||
flags bitset32
|
flags bitset32
|
||||||
|
|
||||||
Esc uint16 // EscXXX
|
esc uint16 // EscXXX
|
||||||
|
|
||||||
Op Op
|
op Op
|
||||||
aux uint8
|
aux uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) GetLeft() *Node { return n.Left }
|
func (n *Node) Left() *Node { return n.left }
|
||||||
func (n *Node) SetLeft(x *Node) { n.Left = x }
|
func (n *Node) SetLeft(x *Node) { n.left = x }
|
||||||
func (n *Node) GetRight() *Node { return n.Right }
|
func (n *Node) Right() *Node { return n.right }
|
||||||
func (n *Node) SetRight(x *Node) { n.Right = x }
|
func (n *Node) SetRight(x *Node) { n.right = x }
|
||||||
func (n *Node) GetOrig() *Node { return n.Orig }
|
func (n *Node) Orig() *Node { return n.orig }
|
||||||
func (n *Node) SetOrig(x *Node) { n.Orig = x }
|
func (n *Node) SetOrig(x *Node) { n.orig = x }
|
||||||
func (n *Node) GetType() *types.Type { return n.Type }
|
func (n *Node) Type() *types.Type { return n.typ }
|
||||||
func (n *Node) SetType(x *types.Type) { n.Type = x }
|
func (n *Node) SetType(x *types.Type) { n.typ = x }
|
||||||
func (n *Node) GetFunc() *Func { return n.Func }
|
func (n *Node) Func() *Func { return n.fn }
|
||||||
func (n *Node) SetFunc(x *Func) { n.Func = x }
|
func (n *Node) SetFunc(x *Func) { n.fn = x }
|
||||||
func (n *Node) GetName() *Name { return n.Name }
|
func (n *Node) Name() *Name { return n.name }
|
||||||
func (n *Node) SetName(x *Name) { n.Name = x }
|
func (n *Node) SetName(x *Name) { n.name = x }
|
||||||
func (n *Node) GetSym() *types.Sym { return n.Sym }
|
func (n *Node) Sym() *types.Sym { return n.sym }
|
||||||
func (n *Node) SetSym(x *types.Sym) { n.Sym = x }
|
func (n *Node) SetSym(x *types.Sym) { n.sym = x }
|
||||||
func (n *Node) GetPos() src.XPos { return n.Pos }
|
func (n *Node) Pos() src.XPos { return n.pos }
|
||||||
func (n *Node) SetPos(x src.XPos) { n.Pos = x }
|
func (n *Node) SetPos(x src.XPos) { n.pos = x }
|
||||||
func (n *Node) GetXoffset() int64 { return n.Xoffset }
|
func (n *Node) Offset() int64 { return n.offset }
|
||||||
func (n *Node) SetXoffset(x int64) { n.Xoffset = x }
|
func (n *Node) SetOffset(x int64) { n.offset = x }
|
||||||
func (n *Node) GetEsc() uint16 { return n.Esc }
|
func (n *Node) Esc() uint16 { return n.esc }
|
||||||
func (n *Node) SetEsc(x uint16) { n.Esc = x }
|
func (n *Node) SetEsc(x uint16) { n.esc = x }
|
||||||
func (n *Node) GetOp() Op { return n.Op }
|
func (n *Node) Op() Op { return n.op }
|
||||||
func (n *Node) SetOp(x Op) { n.Op = x }
|
func (n *Node) SetOp(x Op) { n.op = x }
|
||||||
func (n *Node) GetNinit() Nodes { return n.Ninit }
|
func (n *Node) Init() Nodes { return n.init }
|
||||||
func (n *Node) SetNinit(x Nodes) { n.Ninit = x }
|
func (n *Node) SetInit(x Nodes) { n.init = x }
|
||||||
func (n *Node) PtrNinit() *Nodes { return &n.Ninit }
|
func (n *Node) PtrInit() *Nodes { return &n.init }
|
||||||
func (n *Node) GetNbody() Nodes { return n.Nbody }
|
func (n *Node) Body() Nodes { return n.body }
|
||||||
func (n *Node) SetNbody(x Nodes) { n.Nbody = x }
|
func (n *Node) SetBody(x Nodes) { n.body = x }
|
||||||
func (n *Node) PtrNbody() *Nodes { return &n.Nbody }
|
func (n *Node) PtrBody() *Nodes { return &n.body }
|
||||||
func (n *Node) GetList() Nodes { return n.List }
|
func (n *Node) List() Nodes { return n.list }
|
||||||
func (n *Node) SetList(x Nodes) { n.List = x }
|
func (n *Node) SetList(x Nodes) { n.list = x }
|
||||||
func (n *Node) PtrList() *Nodes { return &n.List }
|
func (n *Node) PtrList() *Nodes { return &n.list }
|
||||||
func (n *Node) GetRlist() Nodes { return n.Rlist }
|
func (n *Node) Rlist() Nodes { return n.rlist }
|
||||||
func (n *Node) SetRlist(x Nodes) { n.Rlist = x }
|
func (n *Node) SetRlist(x Nodes) { n.rlist = x }
|
||||||
func (n *Node) PtrRlist() *Nodes { return &n.Rlist }
|
func (n *Node) PtrRlist() *Nodes { return &n.rlist }
|
||||||
|
|
||||||
func (n *Node) ResetAux() {
|
func (n *Node) ResetAux() {
|
||||||
n.aux = 0
|
n.aux = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) SubOp() Op {
|
func (n *Node) SubOp() Op {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case OASOP, ONAME:
|
case OASOP, ONAME:
|
||||||
default:
|
default:
|
||||||
base.Fatalf("unexpected op: %v", n.Op)
|
base.Fatalf("unexpected op: %v", n.Op())
|
||||||
}
|
}
|
||||||
return Op(n.aux)
|
return Op(n.aux)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) SetSubOp(op Op) {
|
func (n *Node) SetSubOp(op Op) {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case OASOP, ONAME:
|
case OASOP, ONAME:
|
||||||
default:
|
default:
|
||||||
base.Fatalf("unexpected op: %v", n.Op)
|
base.Fatalf("unexpected op: %v", n.Op())
|
||||||
}
|
}
|
||||||
n.aux = uint8(op)
|
n.aux = uint8(op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) IndexMapLValue() bool {
|
func (n *Node) IndexMapLValue() bool {
|
||||||
if n.Op != OINDEXMAP {
|
if n.Op() != OINDEXMAP {
|
||||||
base.Fatalf("unexpected op: %v", n.Op)
|
base.Fatalf("unexpected op: %v", n.Op())
|
||||||
}
|
}
|
||||||
return n.aux != 0
|
return n.aux != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) SetIndexMapLValue(b bool) {
|
func (n *Node) SetIndexMapLValue(b bool) {
|
||||||
if n.Op != OINDEXMAP {
|
if n.Op() != OINDEXMAP {
|
||||||
base.Fatalf("unexpected op: %v", n.Op)
|
base.Fatalf("unexpected op: %v", n.Op())
|
||||||
}
|
}
|
||||||
if b {
|
if b {
|
||||||
n.aux = 1
|
n.aux = 1
|
||||||
|
|
@ -142,31 +142,31 @@ func (n *Node) SetIndexMapLValue(b bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) TChanDir() types.ChanDir {
|
func (n *Node) TChanDir() types.ChanDir {
|
||||||
if n.Op != OTCHAN {
|
if n.Op() != OTCHAN {
|
||||||
base.Fatalf("unexpected op: %v", n.Op)
|
base.Fatalf("unexpected op: %v", n.Op())
|
||||||
}
|
}
|
||||||
return types.ChanDir(n.aux)
|
return types.ChanDir(n.aux)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) SetTChanDir(dir types.ChanDir) {
|
func (n *Node) SetTChanDir(dir types.ChanDir) {
|
||||||
if n.Op != OTCHAN {
|
if n.Op() != OTCHAN {
|
||||||
base.Fatalf("unexpected op: %v", n.Op)
|
base.Fatalf("unexpected op: %v", n.Op())
|
||||||
}
|
}
|
||||||
n.aux = uint8(dir)
|
n.aux = uint8(dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsSynthetic(n *Node) bool {
|
func IsSynthetic(n *Node) bool {
|
||||||
name := n.Sym.Name
|
name := n.Sym().Name
|
||||||
return name[0] == '.' || name[0] == '~'
|
return name[0] == '.' || name[0] == '~'
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAutoTmp indicates if n was created by the compiler as a temporary,
|
// IsAutoTmp indicates if n was created by the compiler as a temporary,
|
||||||
// based on the setting of the .AutoTemp flag in n's Name.
|
// based on the setting of the .AutoTemp flag in n's Name.
|
||||||
func IsAutoTmp(n *Node) bool {
|
func IsAutoTmp(n *Node) bool {
|
||||||
if n == nil || n.Op != ONAME {
|
if n == nil || n.Op() != ONAME {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return n.Name.AutoTemp()
|
return n.Name().AutoTemp()
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
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) SetTransient(b bool) { n.flags.set(nodeTransient, b) }
|
||||||
func (n *Node) SetHasCall(b bool) { n.flags.set(nodeHasCall, 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) SetLikely(b bool) { n.flags.set(nodeLikely, b) }
|
||||||
func (n *Node) SetHasVal(b bool) { n.flags.set(nodeHasVal, 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) setHasOpt(b bool) { n.flags.set(nodeHasOpt, b) }
|
||||||
func (n *Node) SetEmbedded(b bool) { n.flags.set(nodeEmbedded, b) }
|
func (n *Node) SetEmbedded(b bool) { n.flags.set(nodeEmbedded, b) }
|
||||||
|
|
||||||
// MarkNonNil marks a pointer n as being guaranteed non-nil,
|
// 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
|
// During conversion to SSA, non-nil pointers won't have nil checks
|
||||||
// inserted before dereferencing. See state.exprPtr.
|
// inserted before dereferencing. See state.exprPtr.
|
||||||
func (n *Node) MarkNonNil() {
|
func (n *Node) MarkNonNil() {
|
||||||
if !n.Type.IsPtr() && !n.Type.IsUnsafePtr() {
|
if !n.Type().IsPtr() && !n.Type().IsUnsafePtr() {
|
||||||
base.Fatalf("MarkNonNil(%v), type %v", n, n.Type)
|
base.Fatalf("MarkNonNil(%v), type %v", n, n.Type())
|
||||||
}
|
}
|
||||||
n.flags.set(nodeNonNil, true)
|
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 dereferencing operation, n does not need nil checks.
|
||||||
// When n is a makeslice+copy operation, n does not need length and cap checks.
|
// When n is a makeslice+copy operation, n does not need length and cap checks.
|
||||||
func (n *Node) SetBounded(b bool) {
|
func (n *Node) SetBounded(b bool) {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case OINDEX, OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR:
|
case OINDEX, OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR:
|
||||||
// No bounds checks needed.
|
// No bounds checks needed.
|
||||||
case ODOTPTR, ODEREF:
|
case ODOTPTR, ODEREF:
|
||||||
|
|
@ -265,14 +265,14 @@ func (n *Node) SetBounded(b bool) {
|
||||||
|
|
||||||
// MarkReadonly indicates that n is an ONAME with readonly contents.
|
// MarkReadonly indicates that n is an ONAME with readonly contents.
|
||||||
func (n *Node) MarkReadonly() {
|
func (n *Node) MarkReadonly() {
|
||||||
if n.Op != ONAME {
|
if n.Op() != ONAME {
|
||||||
base.Fatalf("Node.MarkReadonly %v", n.Op)
|
base.Fatalf("Node.MarkReadonly %v", n.Op())
|
||||||
}
|
}
|
||||||
n.Name.SetReadonly(true)
|
n.Name().SetReadonly(true)
|
||||||
// Mark the linksym as readonly immediately
|
// Mark the linksym as readonly immediately
|
||||||
// so that the SSA backend can use this information.
|
// so that the SSA backend can use this information.
|
||||||
// It will be overridden later during dumpglobls.
|
// 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.
|
// Val returns the constant.Value for the node.
|
||||||
|
|
@ -280,7 +280,7 @@ func (n *Node) Val() constant.Value {
|
||||||
if !n.HasVal() {
|
if !n.HasVal() {
|
||||||
return constant.MakeUnknown()
|
return constant.MakeUnknown()
|
||||||
}
|
}
|
||||||
return *n.E.(*constant.Value)
|
return *n.e.(*constant.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetVal sets the constant.Value for the node,
|
// SetVal sets the constant.Value for the node,
|
||||||
|
|
@ -291,11 +291,11 @@ func (n *Node) SetVal(v constant.Value) {
|
||||||
Dump("have Opt", n)
|
Dump("have Opt", n)
|
||||||
base.Fatalf("have Opt")
|
base.Fatalf("have Opt")
|
||||||
}
|
}
|
||||||
if n.Op == OLITERAL {
|
if n.Op() == OLITERAL {
|
||||||
AssertValidTypeForConst(n.Type, v)
|
AssertValidTypeForConst(n.Type(), v)
|
||||||
}
|
}
|
||||||
n.SetHasVal(true)
|
n.setHasVal(true)
|
||||||
n.E = &v
|
n.e = &v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opt returns the optimizer data for the node.
|
// Opt returns the optimizer data for the node.
|
||||||
|
|
@ -303,7 +303,7 @@ func (n *Node) Opt() interface{} {
|
||||||
if !n.HasOpt() {
|
if !n.HasOpt() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return n.E
|
return n.e
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetOpt sets the optimizer data for the node, which must not have been used with SetVal.
|
// 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{}) {
|
func (n *Node) SetOpt(x interface{}) {
|
||||||
if x == nil {
|
if x == nil {
|
||||||
if n.HasOpt() {
|
if n.HasOpt() {
|
||||||
n.SetHasOpt(false)
|
n.setHasOpt(false)
|
||||||
n.E = nil
|
n.e = nil
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -321,22 +321,22 @@ func (n *Node) SetOpt(x interface{}) {
|
||||||
Dump("have Val", n)
|
Dump("have Val", n)
|
||||||
base.Fatalf("have Val")
|
base.Fatalf("have Val")
|
||||||
}
|
}
|
||||||
n.SetHasOpt(true)
|
n.setHasOpt(true)
|
||||||
n.E = x
|
n.e = x
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Iota() int64 {
|
func (n *Node) Iota() int64 {
|
||||||
return n.Xoffset
|
return n.Offset()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) SetIota(x int64) {
|
func (n *Node) SetIota(x int64) {
|
||||||
n.Xoffset = x
|
n.SetOffset(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
// mayBeShared reports whether n may occur in multiple places in the AST.
|
// mayBeShared reports whether n may occur in multiple places in the AST.
|
||||||
// Extra care must be taken when mutating such a node.
|
// Extra care must be taken when mutating such a node.
|
||||||
func MayBeShared(n *Node) bool {
|
func MayBeShared(n *Node) bool {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case ONAME, OLITERAL, ONIL, OTYPE:
|
case ONAME, OLITERAL, ONIL, OTYPE:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -345,10 +345,10 @@ func MayBeShared(n *Node) bool {
|
||||||
|
|
||||||
// funcname returns the name (without the package) of the function n.
|
// funcname returns the name (without the package) of the function n.
|
||||||
func FuncName(n *Node) string {
|
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 "<nil>"
|
return "<nil>"
|
||||||
}
|
}
|
||||||
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.
|
// 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 {
|
if n == nil {
|
||||||
return "<nil>"
|
return "<nil>"
|
||||||
}
|
}
|
||||||
if n.Op == ONAME {
|
if n.Op() == ONAME {
|
||||||
s = n.Sym
|
s = n.Sym()
|
||||||
} else {
|
} else {
|
||||||
if n.Func == nil || n.Func.Nname == nil {
|
if n.Func() == nil || n.Func().Nname == nil {
|
||||||
return "<nil>"
|
return "<nil>"
|
||||||
}
|
}
|
||||||
s = n.Func.Nname.Sym
|
s = n.Func().Nname.Sym()
|
||||||
}
|
}
|
||||||
pkg := s.Pkg
|
pkg := s.Pkg
|
||||||
|
|
||||||
|
|
@ -1142,12 +1142,12 @@ func Inspect(n *Node, f func(*Node) bool) {
|
||||||
if n == nil || !f(n) {
|
if n == nil || !f(n) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
InspectList(n.Ninit, f)
|
InspectList(n.Init(), f)
|
||||||
Inspect(n.Left, f)
|
Inspect(n.Left(), f)
|
||||||
Inspect(n.Right, f)
|
Inspect(n.Right(), f)
|
||||||
InspectList(n.List, f)
|
InspectList(n.List(), f)
|
||||||
InspectList(n.Nbody, f)
|
InspectList(n.Body(), f)
|
||||||
InspectList(n.Rlist, f)
|
InspectList(n.Rlist(), f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func InspectList(l Nodes, f func(*Node) bool) {
|
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
|
f Func
|
||||||
}
|
}
|
||||||
n = &x.n
|
n = &x.n
|
||||||
n.Func = &x.f
|
n.SetFunc(&x.f)
|
||||||
n.Func.Decl = n
|
n.Func().Decl = n
|
||||||
case ONAME:
|
case ONAME:
|
||||||
base.Fatalf("use newname instead")
|
base.Fatalf("use newname instead")
|
||||||
case OLABEL, OPACK:
|
case OLABEL, OPACK:
|
||||||
|
|
@ -1252,16 +1252,16 @@ func NodAt(pos src.XPos, op Op, nleft, nright *Node) *Node {
|
||||||
m Name
|
m Name
|
||||||
}
|
}
|
||||||
n = &x.n
|
n = &x.n
|
||||||
n.Name = &x.m
|
n.SetName(&x.m)
|
||||||
default:
|
default:
|
||||||
n = new(Node)
|
n = new(Node)
|
||||||
}
|
}
|
||||||
n.Op = op
|
n.SetOp(op)
|
||||||
n.Left = nleft
|
n.SetLeft(nleft)
|
||||||
n.Right = nright
|
n.SetRight(nright)
|
||||||
n.Pos = pos
|
n.SetPos(pos)
|
||||||
n.Xoffset = types.BADWIDTH
|
n.SetOffset(types.BADWIDTH)
|
||||||
n.Orig = n
|
n.SetOrig(n)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1278,14 +1278,14 @@ func NewNameAt(pos src.XPos, s *types.Sym) *Node {
|
||||||
p Param
|
p Param
|
||||||
}
|
}
|
||||||
n := &x.n
|
n := &x.n
|
||||||
n.Name = &x.m
|
n.SetName(&x.m)
|
||||||
n.Name.Param = &x.p
|
n.Name().Param = &x.p
|
||||||
|
|
||||||
n.Op = ONAME
|
n.SetOp(ONAME)
|
||||||
n.Pos = pos
|
n.SetPos(pos)
|
||||||
n.Orig = n
|
n.SetOrig(n)
|
||||||
|
|
||||||
n.Sym = s
|
n.SetSym(s)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1358,7 +1358,7 @@ func OrigSym(s *types.Sym) *types.Sym {
|
||||||
return nil
|
return nil
|
||||||
case 'b': // originally the blank identifier _
|
case 'b': // originally the blank identifier _
|
||||||
// TODO(mdempsky): Does s.Pkg matter here?
|
// TODO(mdempsky): Does s.Pkg matter here?
|
||||||
return BlankNode.Sym
|
return BlankNode.Sym()
|
||||||
}
|
}
|
||||||
return s
|
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].
|
// 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.
|
// n must be a slice expression. max is nil if n is a simple slice expression.
|
||||||
func (n *Node) SliceBounds() (low, high, max *Node) {
|
func (n *Node) SliceBounds() (low, high, max *Node) {
|
||||||
if n.List.Len() == 0 {
|
if n.List().Len() == 0 {
|
||||||
return nil, nil, nil
|
return nil, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case OSLICE, OSLICEARR, OSLICESTR:
|
case OSLICE, OSLICEARR, OSLICESTR:
|
||||||
s := n.List.Slice()
|
s := n.List().Slice()
|
||||||
return s[0], s[1], nil
|
return s[0], s[1], nil
|
||||||
case OSLICE3, OSLICE3ARR:
|
case OSLICE3, OSLICE3ARR:
|
||||||
s := n.List.Slice()
|
s := n.List().Slice()
|
||||||
return s[0], s[1], s[2]
|
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
|
return nil, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSliceBounds sets n's slice bounds, where n is a slice expression.
|
// 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.
|
// 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) {
|
func (n *Node) SetSliceBounds(low, high, max *Node) {
|
||||||
switch n.Op {
|
switch n.Op() {
|
||||||
case OSLICE, OSLICEARR, OSLICESTR:
|
case OSLICE, OSLICEARR, OSLICESTR:
|
||||||
if max != nil {
|
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 s == nil {
|
||||||
if low == nil && high == nil {
|
if low == nil && high == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n.List.Set2(low, high)
|
n.PtrList().Set2(low, high)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s[0] = low
|
s[0] = low
|
||||||
s[1] = high
|
s[1] = high
|
||||||
return
|
return
|
||||||
case OSLICE3, OSLICE3ARR:
|
case OSLICE3, OSLICE3ARR:
|
||||||
s := n.List.Slice()
|
s := n.List().Slice()
|
||||||
if s == nil {
|
if s == nil {
|
||||||
if low == nil && high == nil && max == nil {
|
if low == nil && high == nil && max == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n.List.Set3(low, high, max)
|
n.PtrList().Set3(low, high, max)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s[0] = low
|
s[0] = low
|
||||||
|
|
@ -1423,7 +1423,7 @@ func (n *Node) SetSliceBounds(low, high, max *Node) {
|
||||||
s[2] = max
|
s[2] = max
|
||||||
return
|
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).
|
// IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR).
|
||||||
|
|
@ -1511,7 +1511,7 @@ func (n *Node) RawCopy() *Node {
|
||||||
// Orig pointing to itself.
|
// Orig pointing to itself.
|
||||||
func SepCopy(n *Node) *Node {
|
func SepCopy(n *Node) *Node {
|
||||||
copy := *n
|
copy := *n
|
||||||
copy.Orig = ©
|
copy.orig = ©
|
||||||
return ©
|
return ©
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1524,8 +1524,8 @@ func SepCopy(n *Node) *Node {
|
||||||
// messages; see issues #26855, #27765).
|
// messages; see issues #26855, #27765).
|
||||||
func Copy(n *Node) *Node {
|
func Copy(n *Node) *Node {
|
||||||
copy := *n
|
copy := *n
|
||||||
if n.Orig == n {
|
if n.Orig() == n {
|
||||||
copy.Orig = ©
|
copy.orig = ©
|
||||||
}
|
}
|
||||||
return ©
|
return ©
|
||||||
}
|
}
|
||||||
|
|
@ -1534,18 +1534,18 @@ func Copy(n *Node) *Node {
|
||||||
func IsNil(n *Node) bool {
|
func IsNil(n *Node) bool {
|
||||||
// Check n.Orig because constant propagation may produce typed nil constants,
|
// Check n.Orig because constant propagation may produce typed nil constants,
|
||||||
// which don't exist in the Go spec.
|
// which don't exist in the Go spec.
|
||||||
return n.Orig.Op == ONIL
|
return n.Orig().Op() == ONIL
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsBlank(n *Node) bool {
|
func IsBlank(n *Node) bool {
|
||||||
if n == nil {
|
if n == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return n.Sym.IsBlank()
|
return n.Sym().IsBlank()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsMethod reports whether n is a method.
|
// IsMethod reports whether n is a method.
|
||||||
// n must be a function or a method.
|
// n must be a function or a method.
|
||||||
func IsMethod(n *Node) bool {
|
func IsMethod(n *Node) bool {
|
||||||
return n.Type.Recv() != nil
|
return n.Type().Recv() != nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func ConstType(n *Node) constant.Kind {
|
func ConstType(n *Node) constant.Kind {
|
||||||
if n == nil || n.Op != OLITERAL {
|
if n == nil || n.Op() != OLITERAL {
|
||||||
return constant.Unknown
|
return constant.Unknown
|
||||||
}
|
}
|
||||||
return n.Val().Kind()
|
return n.Val().Kind()
|
||||||
|
|
@ -32,7 +32,7 @@ func ConstValue(n *Node) interface{} {
|
||||||
case constant.String:
|
case constant.String:
|
||||||
return constant.StringVal(v)
|
return constant.StringVal(v)
|
||||||
case constant.Int:
|
case constant.Int:
|
||||||
return Int64Val(n.Type, v)
|
return Int64Val(n.Type(), v)
|
||||||
case constant.Float:
|
case constant.Float:
|
||||||
return Float64Val(v)
|
return Float64Val(v)
|
||||||
case constant.Complex:
|
case constant.Complex:
|
||||||
|
|
@ -94,7 +94,7 @@ func ValidTypeForConst(t *types.Type, v constant.Value) bool {
|
||||||
func NewLiteral(v constant.Value) *Node {
|
func NewLiteral(v constant.Value) *Node {
|
||||||
n := Nod(OLITERAL, nil, nil)
|
n := Nod(OLITERAL, nil, nil)
|
||||||
if k := v.Kind(); k != constant.Unknown {
|
if k := v.Kind(); k != constant.Unknown {
|
||||||
n.Type = idealType(k)
|
n.SetType(idealType(k))
|
||||||
n.SetVal(v)
|
n.SetVal(v)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,7 @@ func nilcheckelim2(f *Func) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if v.Type.IsMemory() || v.Type.IsTuple() && v.Type.FieldType(1).IsMemory() {
|
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.
|
// These ops don't really change memory.
|
||||||
continue
|
continue
|
||||||
// Note: OpVarDef requires that the defined variable not have pointers.
|
// Note: OpVarDef requires that the defined variable not have pointers.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue