[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:
Russ Cox 2020-11-22 09:59:15 -05:00
parent 41ab6689ed
commit acb4d1cef1
44 changed files with 5188 additions and 5186 deletions

View file

@ -18,14 +18,14 @@ func (p *noder) funcLit(expr *syntax.FuncLit) *ir.Node {
ntype := p.typeExpr(expr.Type)
dcl := p.nod(expr, ir.ODCLFUNC, nil, nil)
fn := dcl.Func
fn := dcl.Func()
fn.SetIsHiddenClosure(Curfn != nil)
fn.Nname = newfuncnamel(p.pos(expr), ir.BlankNode.Sym, fn) // filled in by typecheckclosure
fn.Nname.Name.Param.Ntype = xtype
fn.Nname.Name.Defn = dcl
fn.Nname = newfuncnamel(p.pos(expr), ir.BlankNode.Sym(), fn) // filled in by typecheckclosure
fn.Nname.Name().Param.Ntype = xtype
fn.Nname.Name().Defn = dcl
clo := p.nod(expr, ir.OCLOSURE, nil, nil)
clo.Func = fn
clo.SetFunc(fn)
fn.ClosureType = ntype
fn.OClosure = clo
@ -37,8 +37,8 @@ func (p *noder) funcLit(expr *syntax.FuncLit) *ir.Node {
// make the list of pointers for the closure call.
for _, v := range fn.ClosureVars.Slice() {
// Unlink from v1; see comment in syntax.go type Param for these fields.
v1 := v.Name.Defn
v1.Name.Param.Innermost = v.Name.Param.Outer
v1 := v.Name().Defn
v1.Name().Param.Innermost = v.Name().Param.Outer
// If the closure usage of v is not dense,
// we need to make it dense; now that we're out
@ -68,7 +68,7 @@ func (p *noder) funcLit(expr *syntax.FuncLit) *ir.Node {
// obtains f3's v, creating it if necessary (as it is in the example).
//
// capturevars will decide whether to use v directly or &v.
v.Name.Param.Outer = oldname(v.Sym)
v.Name().Param.Outer = oldname(v.Sym())
}
return clo
@ -79,7 +79,7 @@ func (p *noder) funcLit(expr *syntax.FuncLit) *ir.Node {
// TODO: This creation of the named function should probably really be done in a
// separate pass from type-checking.
func typecheckclosure(clo *ir.Node, top int) {
fn := clo.Func
fn := clo.Func()
dcl := fn.Decl
// Set current associated iota value, so iota can be used inside
// function in ConstSpec, see issue #22344
@ -88,7 +88,7 @@ func typecheckclosure(clo *ir.Node, top int) {
}
fn.ClosureType = typecheck(fn.ClosureType, ctxType)
clo.Type = fn.ClosureType.Type
clo.SetType(fn.ClosureType.Type())
fn.ClosureCalled = top&ctxCallee != 0
// Do not typecheck dcl twice, otherwise, we will end up pushing
@ -99,22 +99,22 @@ func typecheckclosure(clo *ir.Node, top int) {
}
for _, ln := range fn.ClosureVars.Slice() {
n := ln.Name.Defn
if !n.Name.Captured() {
n.Name.SetCaptured(true)
if n.Name.Decldepth == 0 {
n := ln.Name().Defn
if !n.Name().Captured() {
n.Name().SetCaptured(true)
if n.Name().Decldepth == 0 {
base.Fatalf("typecheckclosure: var %S does not have decldepth assigned", n)
}
// Ignore assignments to the variable in straightline code
// preceding the first capturing by a closure.
if n.Name.Decldepth == decldepth {
n.Name.SetAssigned(false)
if n.Name().Decldepth == decldepth {
n.Name().SetAssigned(false)
}
}
}
fn.Nname.Sym = closurename(Curfn)
fn.Nname.SetSym(closurename(Curfn))
setNodeNameFunc(fn.Nname)
dcl = typecheck(dcl, ctxStmt)
@ -122,12 +122,12 @@ func typecheckclosure(clo *ir.Node, top int) {
// At top level (in a variable initialization: curfn==nil) we're not
// ready to type check code yet; we'll check it later, because the
// underlying closure function we create is added to xtop.
if Curfn != nil && clo.Type != nil {
if Curfn != nil && clo.Type() != nil {
oldfn := Curfn
Curfn = dcl
olddd := decldepth
decldepth = 1
typecheckslice(dcl.Nbody.Slice(), ctxStmt)
typecheckslice(dcl.Body().Slice(), ctxStmt)
decldepth = olddd
Curfn = oldfn
}
@ -146,7 +146,7 @@ func closurename(outerfunc *ir.Node) *types.Sym {
gen := &globClosgen
if outerfunc != nil {
if outerfunc.Func.OClosure != nil {
if outerfunc.Func().OClosure != nil {
prefix = ""
}
@ -155,8 +155,8 @@ func closurename(outerfunc *ir.Node) *types.Sym {
// There may be multiple functions named "_". In those
// cases, we can't use their individual Closgens as it
// would lead to name clashes.
if !ir.IsBlank(outerfunc.Func.Nname) {
gen = &outerfunc.Func.Closgen
if !ir.IsBlank(outerfunc.Func().Nname) {
gen = &outerfunc.Func().Closgen
}
}
@ -174,12 +174,12 @@ var capturevarscomplete bool
// after capturing (effectively constant).
func capturevars(dcl *ir.Node) {
lno := base.Pos
base.Pos = dcl.Pos
fn := dcl.Func
base.Pos = dcl.Pos()
fn := dcl.Func()
cvars := fn.ClosureVars.Slice()
out := cvars[:0]
for _, v := range cvars {
if v.Type == nil {
if v.Type() == nil {
// If v.Type is nil, it means v looked like it
// was going to be used in the closure, but
// isn't. This happens in struct literals like
@ -192,29 +192,29 @@ func capturevars(dcl *ir.Node) {
// type check the & of closed variables outside the closure,
// so that the outer frame also grabs them and knows they escape.
dowidth(v.Type)
dowidth(v.Type())
outer := v.Name.Param.Outer
outermost := v.Name.Defn
outer := v.Name().Param.Outer
outermost := v.Name().Defn
// out parameters will be assigned to implicitly upon return.
if outermost.Class() != ir.PPARAMOUT && !outermost.Name.Addrtaken() && !outermost.Name.Assigned() && v.Type.Width <= 128 {
v.Name.SetByval(true)
if outermost.Class() != ir.PPARAMOUT && !outermost.Name().Addrtaken() && !outermost.Name().Assigned() && v.Type().Width <= 128 {
v.Name().SetByval(true)
} else {
outermost.Name.SetAddrtaken(true)
outermost.Name().SetAddrtaken(true)
outer = ir.Nod(ir.OADDR, outer, nil)
}
if base.Flag.LowerM > 1 {
var name *types.Sym
if v.Name.Curfn != nil && v.Name.Curfn.Func.Nname != nil {
name = v.Name.Curfn.Func.Nname.Sym
if v.Name().Curfn != nil && v.Name().Curfn.Func().Nname != nil {
name = v.Name().Curfn.Func().Nname.Sym()
}
how := "ref"
if v.Name.Byval() {
if v.Name().Byval() {
how = "value"
}
base.WarnfAt(v.Pos, "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym, outermost.Name.Addrtaken(), outermost.Name.Assigned(), int32(v.Type.Width))
base.WarnfAt(v.Pos(), "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym(), outermost.Name().Addrtaken(), outermost.Name().Assigned(), int32(v.Type().Width))
}
outer = typecheck(outer, ctxExpr)
@ -229,8 +229,8 @@ func capturevars(dcl *ir.Node) {
// It transform closure bodies to properly reference captured variables.
func transformclosure(dcl *ir.Node) {
lno := base.Pos
base.Pos = dcl.Pos
fn := dcl.Func
base.Pos = dcl.Pos()
fn := dcl.Func()
if fn.ClosureCalled {
// If the closure is directly called, we transform it to a plain function call
@ -255,33 +255,33 @@ func transformclosure(dcl *ir.Node) {
var params []*types.Field
var decls []*ir.Node
for _, v := range fn.ClosureVars.Slice() {
if !v.Name.Byval() {
if !v.Name().Byval() {
// If v of type T is captured by reference,
// we introduce function param &v *T
// and v remains PAUTOHEAP with &v heapaddr
// (accesses will implicitly deref &v).
addr := NewName(lookup("&" + v.Sym.Name))
addr.Type = types.NewPtr(v.Type)
v.Name.Param.Heapaddr = addr
addr := NewName(lookup("&" + v.Sym().Name))
addr.SetType(types.NewPtr(v.Type()))
v.Name().Param.Heapaddr = addr
v = addr
}
v.SetClass(ir.PPARAM)
decls = append(decls, v)
fld := types.NewField(src.NoXPos, v.Sym, v.Type)
fld := types.NewField(src.NoXPos, v.Sym(), v.Type())
fld.Nname = ir.AsTypesNode(v)
params = append(params, fld)
}
if len(params) > 0 {
// Prepend params and decls.
f.Type.Params().SetFields(append(params, f.Type.Params().FieldSlice()...))
f.Type().Params().SetFields(append(params, f.Type().Params().FieldSlice()...))
fn.Dcl = append(decls, fn.Dcl...)
}
dowidth(f.Type)
dcl.Type = f.Type // update type of ODCLFUNC
dowidth(f.Type())
dcl.SetType(f.Type()) // update type of ODCLFUNC
} else {
// The closure is not called, so it is going to stay as closure.
var body []*ir.Node
@ -290,15 +290,15 @@ func transformclosure(dcl *ir.Node) {
// cv refers to the field inside of closure OSTRUCTLIT.
cv := ir.Nod(ir.OCLOSUREVAR, nil, nil)
cv.Type = v.Type
if !v.Name.Byval() {
cv.Type = types.NewPtr(v.Type)
cv.SetType(v.Type())
if !v.Name().Byval() {
cv.SetType(types.NewPtr(v.Type()))
}
offset = Rnd(offset, int64(cv.Type.Align))
cv.Xoffset = offset
offset += cv.Type.Width
offset = Rnd(offset, int64(cv.Type().Align))
cv.SetOffset(offset)
offset += cv.Type().Width
if v.Name.Byval() && v.Type.Width <= int64(2*Widthptr) {
if v.Name().Byval() && v.Type().Width <= int64(2*Widthptr) {
// If it is a small variable captured by value, downgrade it to PAUTO.
v.SetClass(ir.PAUTO)
fn.Dcl = append(fn.Dcl, v)
@ -306,14 +306,14 @@ func transformclosure(dcl *ir.Node) {
} else {
// Declare variable holding addresses taken from closure
// and initialize in entry prologue.
addr := NewName(lookup("&" + v.Sym.Name))
addr.Type = types.NewPtr(v.Type)
addr := NewName(lookup("&" + v.Sym().Name))
addr.SetType(types.NewPtr(v.Type()))
addr.SetClass(ir.PAUTO)
addr.Name.SetUsed(true)
addr.Name.Curfn = dcl
addr.Name().SetUsed(true)
addr.Name().Curfn = dcl
fn.Dcl = append(fn.Dcl, addr)
v.Name.Param.Heapaddr = addr
if v.Name.Byval() {
v.Name().Param.Heapaddr = addr
if v.Name().Byval() {
cv = ir.Nod(ir.OADDR, cv, nil)
}
body = append(body, ir.Nod(ir.OAS, addr, cv))
@ -333,21 +333,21 @@ func transformclosure(dcl *ir.Node) {
// hasemptycvars reports whether closure clo has an
// empty list of captured vars.
func hasemptycvars(clo *ir.Node) bool {
return clo.Func.ClosureVars.Len() == 0
return clo.Func().ClosureVars.Len() == 0
}
// closuredebugruntimecheck applies boilerplate checks for debug flags
// and compiling runtime
func closuredebugruntimecheck(clo *ir.Node) {
if base.Debug.Closure > 0 {
if clo.Esc == EscHeap {
base.WarnfAt(clo.Pos, "heap closure, captured vars = %v", clo.Func.ClosureVars)
if clo.Esc() == EscHeap {
base.WarnfAt(clo.Pos(), "heap closure, captured vars = %v", clo.Func().ClosureVars)
} else {
base.WarnfAt(clo.Pos, "stack closure, captured vars = %v", clo.Func.ClosureVars)
base.WarnfAt(clo.Pos(), "stack closure, captured vars = %v", clo.Func().ClosureVars)
}
}
if base.Flag.CompilingRuntime && clo.Esc == EscHeap {
base.ErrorfAt(clo.Pos, "heap-allocated closure, not allowed in runtime")
if base.Flag.CompilingRuntime && clo.Esc() == EscHeap {
base.ErrorfAt(clo.Pos(), "heap-allocated closure, not allowed in runtime")
}
}
@ -371,12 +371,12 @@ func closureType(clo *ir.Node) *types.Type {
fields := []*ir.Node{
namedfield(".F", types.Types[types.TUINTPTR]),
}
for _, v := range clo.Func.ClosureVars.Slice() {
typ := v.Type
if !v.Name.Byval() {
for _, v := range clo.Func().ClosureVars.Slice() {
typ := v.Type()
if !v.Name().Byval() {
typ = types.NewPtr(typ)
}
fields = append(fields, symfield(v.Sym, typ))
fields = append(fields, symfield(v.Sym(), typ))
}
typ := tostruct(fields)
typ.SetNoalg(true)
@ -384,12 +384,12 @@ func closureType(clo *ir.Node) *types.Type {
}
func walkclosure(clo *ir.Node, init *ir.Nodes) *ir.Node {
fn := clo.Func
fn := clo.Func()
// If no closure vars, don't bother wrapping.
if hasemptycvars(clo) {
if base.Debug.Closure > 0 {
base.WarnfAt(clo.Pos, "closure converted to global")
base.WarnfAt(clo.Pos(), "closure converted to global")
}
return fn.Nname
}
@ -398,21 +398,21 @@ func walkclosure(clo *ir.Node, init *ir.Nodes) *ir.Node {
typ := closureType(clo)
clos := ir.Nod(ir.OCOMPLIT, nil, typenod(typ))
clos.Esc = clo.Esc
clos.List.Set(append([]*ir.Node{ir.Nod(ir.OCFUNC, fn.Nname, nil)}, fn.ClosureEnter.Slice()...))
clos.SetEsc(clo.Esc())
clos.PtrList().Set(append([]*ir.Node{ir.Nod(ir.OCFUNC, fn.Nname, nil)}, fn.ClosureEnter.Slice()...))
clos = ir.Nod(ir.OADDR, clos, nil)
clos.Esc = clo.Esc
clos.SetEsc(clo.Esc())
// Force type conversion from *struct to the func type.
clos = convnop(clos, clo.Type)
clos = convnop(clos, clo.Type())
// non-escaping temp to use, if any.
if x := prealloc[clo]; x != nil {
if !types.Identical(typ, x.Type) {
if !types.Identical(typ, x.Type()) {
panic("closure type does not match order's assigned type")
}
clos.Left.Right = x
clos.Left().SetRight(x)
delete(prealloc, clo)
}
@ -420,7 +420,7 @@ func walkclosure(clo *ir.Node, init *ir.Nodes) *ir.Node {
}
func typecheckpartialcall(dot *ir.Node, sym *types.Sym) {
switch dot.Op {
switch dot.Op() {
case ir.ODOTINTER, ir.ODOTMETH:
break
@ -429,19 +429,19 @@ func typecheckpartialcall(dot *ir.Node, sym *types.Sym) {
}
// Create top-level function.
dcl := makepartialcall(dot, dot.Type, sym)
dcl.Func.SetWrapper(true)
dot.Op = ir.OCALLPART
dot.Right = NewName(sym)
dot.Type = dcl.Type
dot.Func = dcl.Func
dcl := makepartialcall(dot, dot.Type(), sym)
dcl.Func().SetWrapper(true)
dot.SetOp(ir.OCALLPART)
dot.SetRight(NewName(sym))
dot.SetType(dcl.Type())
dot.SetFunc(dcl.Func())
dot.SetOpt(nil) // clear types.Field from ODOTMETH
}
// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
// for partial calls.
func makepartialcall(dot *ir.Node, t0 *types.Type, meth *types.Sym) *ir.Node {
rcvrtype := dot.Left.Type
rcvrtype := dot.Left().Type()
sym := methodSymSuffix(rcvrtype, meth, "-fm")
if sym.Uniq() {
@ -465,52 +465,52 @@ func makepartialcall(dot *ir.Node, t0 *types.Type, meth *types.Sym) *ir.Node {
// case. See issue 29389.
tfn := ir.Nod(ir.OTFUNC, nil, nil)
tfn.List.Set(structargs(t0.Params(), true))
tfn.Rlist.Set(structargs(t0.Results(), false))
tfn.PtrList().Set(structargs(t0.Params(), true))
tfn.PtrRlist().Set(structargs(t0.Results(), false))
dcl := dclfunc(sym, tfn)
fn := dcl.Func
fn := dcl.Func()
fn.SetDupok(true)
fn.SetNeedctxt(true)
tfn.Type.SetPkg(t0.Pkg())
tfn.Type().SetPkg(t0.Pkg())
// Declare and initialize variable holding receiver.
cv := ir.Nod(ir.OCLOSUREVAR, nil, nil)
cv.Type = rcvrtype
cv.Xoffset = Rnd(int64(Widthptr), int64(cv.Type.Align))
cv.SetType(rcvrtype)
cv.SetOffset(Rnd(int64(Widthptr), int64(cv.Type().Align)))
ptr := NewName(lookup(".this"))
declare(ptr, ir.PAUTO)
ptr.Name.SetUsed(true)
ptr.Name().SetUsed(true)
var body []*ir.Node
if rcvrtype.IsPtr() || rcvrtype.IsInterface() {
ptr.Type = rcvrtype
ptr.SetType(rcvrtype)
body = append(body, ir.Nod(ir.OAS, ptr, cv))
} else {
ptr.Type = types.NewPtr(rcvrtype)
ptr.SetType(types.NewPtr(rcvrtype))
body = append(body, ir.Nod(ir.OAS, ptr, ir.Nod(ir.OADDR, cv, nil)))
}
call := ir.Nod(ir.OCALL, nodSym(ir.OXDOT, ptr, meth), nil)
call.List.Set(paramNnames(tfn.Type))
call.SetIsDDD(tfn.Type.IsVariadic())
call.PtrList().Set(paramNnames(tfn.Type()))
call.SetIsDDD(tfn.Type().IsVariadic())
if t0.NumResults() != 0 {
n := ir.Nod(ir.ORETURN, nil, nil)
n.List.Set1(call)
n.PtrList().Set1(call)
call = n
}
body = append(body, call)
dcl.Nbody.Set(body)
dcl.PtrBody().Set(body)
funcbody()
dcl = typecheck(dcl, ctxStmt)
// Need to typecheck the body of the just-generated wrapper.
// typecheckslice() requires that Curfn is set when processing an ORETURN.
Curfn = dcl
typecheckslice(dcl.Nbody.Slice(), ctxStmt)
typecheckslice(dcl.Body().Slice(), ctxStmt)
sym.Def = ir.AsTypesNode(dcl)
xtop = append(xtop, dcl)
Curfn = savecurfn
@ -525,7 +525,7 @@ func makepartialcall(dot *ir.Node, t0 *types.Type, meth *types.Sym) *ir.Node {
func partialCallType(n *ir.Node) *types.Type {
t := tostruct([]*ir.Node{
namedfield("F", types.Types[types.TUINTPTR]),
namedfield("R", n.Left.Type),
namedfield("R", n.Left().Type()),
})
t.SetNoalg(true)
return t
@ -539,13 +539,13 @@ func walkpartialcall(n *ir.Node, init *ir.Nodes) *ir.Node {
//
// Like walkclosure above.
if n.Left.Type.IsInterface() {
if n.Left().Type().IsInterface() {
// Trigger panic for method on nil interface now.
// Otherwise it happens in the wrapper and is confusing.
n.Left = cheapexpr(n.Left, init)
n.Left = walkexpr(n.Left, nil)
n.SetLeft(cheapexpr(n.Left(), init))
n.SetLeft(walkexpr(n.Left(), nil))
tab := ir.Nod(ir.OITAB, n.Left, nil)
tab := ir.Nod(ir.OITAB, n.Left(), nil)
tab = typecheck(tab, ctxExpr)
c := ir.Nod(ir.OCHECKNIL, tab, nil)
@ -556,21 +556,21 @@ func walkpartialcall(n *ir.Node, init *ir.Nodes) *ir.Node {
typ := partialCallType(n)
clos := ir.Nod(ir.OCOMPLIT, nil, typenod(typ))
clos.Esc = n.Esc
clos.List.Set2(ir.Nod(ir.OCFUNC, n.Func.Nname, nil), n.Left)
clos.SetEsc(n.Esc())
clos.PtrList().Set2(ir.Nod(ir.OCFUNC, n.Func().Nname, nil), n.Left())
clos = ir.Nod(ir.OADDR, clos, nil)
clos.Esc = n.Esc
clos.SetEsc(n.Esc())
// Force type conversion from *struct to the func type.
clos = convnop(clos, n.Type)
clos = convnop(clos, n.Type())
// non-escaping temp to use, if any.
if x := prealloc[n]; x != nil {
if !types.Identical(typ, x.Type) {
if !types.Identical(typ, x.Type()) {
panic("partial call type does not match order's assigned type")
}
clos.Left.Right = x
clos.Left().SetRight(x)
delete(prealloc, n)
}
@ -580,14 +580,14 @@ func walkpartialcall(n *ir.Node, init *ir.Nodes) *ir.Node {
// callpartMethod returns the *types.Field representing the method
// referenced by method value n.
func callpartMethod(n *ir.Node) *types.Field {
if n.Op != ir.OCALLPART {
if n.Op() != ir.OCALLPART {
base.Fatalf("expected OCALLPART, got %v", n)
}
// TODO(mdempsky): Optimize this. If necessary,
// makepartialcall could save m for us somewhere.
var m *types.Field
if lookdot0(n.Right.Sym, n.Left.Type, &m, false) != 1 {
if lookdot0(n.Right().Sym(), n.Left().Type(), &m, false) != 1 {
base.Fatalf("failed to find field for OCALLPART")
}