mirror of
https://github.com/golang/go
synced 2024-11-11 23:20:24 -07:00
[dev.typeparams] cmd/compile: move MethodValueWrapper to walk
walk is the only pass that use the function, so un-export it, too. Change-Id: I32ec64d1c15fda7bb54bd8efa528ed32c102876d Reviewed-on: https://go-review.googlesource.com/c/go/+/330841 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
a8861b907d
commit
f99b3fe2ab
@ -218,86 +218,6 @@ func fnpkg(fn *ir.Name) *types.Pkg {
|
||||
return fn.Sym().Pkg
|
||||
}
|
||||
|
||||
// MethodValueWrapper returns the DCLFUNC node representing the
|
||||
// wrapper function (*-fm) needed for the given method value. If the
|
||||
// wrapper function hasn't already been created yet, it's created and
|
||||
// added to Target.Decls.
|
||||
//
|
||||
// TODO(mdempsky): Move into walk. This isn't part of type checking.
|
||||
func MethodValueWrapper(dot *ir.SelectorExpr) *ir.Func {
|
||||
if dot.Op() != ir.OMETHVALUE {
|
||||
base.Fatalf("MethodValueWrapper: unexpected %v (%v)", dot, dot.Op())
|
||||
}
|
||||
|
||||
t0 := dot.Type()
|
||||
meth := dot.Sel
|
||||
rcvrtype := dot.X.Type()
|
||||
sym := ir.MethodSymSuffix(rcvrtype, meth, "-fm")
|
||||
|
||||
if sym.Uniq() {
|
||||
return sym.Def.(*ir.Func)
|
||||
}
|
||||
sym.SetUniq(true)
|
||||
|
||||
savecurfn := ir.CurFunc
|
||||
saveLineNo := base.Pos
|
||||
ir.CurFunc = nil
|
||||
|
||||
// Set line number equal to the line number where the method is declared.
|
||||
if pos := dot.Selection.Pos; pos.IsKnown() {
|
||||
base.Pos = pos
|
||||
}
|
||||
// Note: !dot.Selection.Pos.IsKnown() happens for method expressions where
|
||||
// the method is implicitly declared. The Error method of the
|
||||
// built-in error type is one such method. We leave the line
|
||||
// number at the use of the method expression in this
|
||||
// case. See issue 29389.
|
||||
|
||||
tfn := ir.NewFuncType(base.Pos, nil,
|
||||
NewFuncParams(t0.Params(), true),
|
||||
NewFuncParams(t0.Results(), false))
|
||||
|
||||
fn := DeclFunc(sym, tfn)
|
||||
fn.SetDupok(true)
|
||||
fn.SetNeedctxt(true)
|
||||
fn.SetWrapper(true)
|
||||
|
||||
// Declare and initialize variable holding receiver.
|
||||
ptr := ir.NewNameAt(base.Pos, Lookup(".this"))
|
||||
ptr.Class = ir.PAUTOHEAP
|
||||
ptr.SetType(rcvrtype)
|
||||
ptr.Curfn = fn
|
||||
ptr.SetIsClosureVar(true)
|
||||
ptr.SetByval(true)
|
||||
fn.ClosureVars = append(fn.ClosureVars, ptr)
|
||||
|
||||
call := ir.NewCallExpr(base.Pos, ir.OCALL, ir.NewSelectorExpr(base.Pos, ir.OXDOT, ptr, meth), nil)
|
||||
call.Args = ir.ParamNames(tfn.Type())
|
||||
call.IsDDD = tfn.Type().IsVariadic()
|
||||
|
||||
var body ir.Node = call
|
||||
if t0.NumResults() != 0 {
|
||||
ret := ir.NewReturnStmt(base.Pos, nil)
|
||||
ret.Results = []ir.Node{call}
|
||||
body = ret
|
||||
}
|
||||
|
||||
fn.Body = []ir.Node{body}
|
||||
FinishFuncBody()
|
||||
|
||||
Func(fn)
|
||||
// Need to typecheck the body of the just-generated wrapper.
|
||||
// typecheckslice() requires that Curfn is set when processing an ORETURN.
|
||||
ir.CurFunc = fn
|
||||
Stmts(fn.Body)
|
||||
sym.Def = fn
|
||||
Target.Decls = append(Target.Decls, fn)
|
||||
ir.CurFunc = savecurfn
|
||||
base.Pos = saveLineNo
|
||||
|
||||
return fn
|
||||
}
|
||||
|
||||
// tcClosure typechecks an OCLOSURE node. It also creates the named
|
||||
// function associated with the closure.
|
||||
// TODO: This creation of the named function should probably really be done in a
|
||||
|
@ -179,7 +179,7 @@ func walkMethodValue(n *ir.SelectorExpr, init *ir.Nodes) ir.Node {
|
||||
|
||||
clos := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(typ), nil)
|
||||
clos.SetEsc(n.Esc())
|
||||
clos.List = []ir.Node{ir.NewUnaryExpr(base.Pos, ir.OCFUNC, typecheck.MethodValueWrapper(n).Nname), n.X}
|
||||
clos.List = []ir.Node{ir.NewUnaryExpr(base.Pos, ir.OCFUNC, methodValueWrapper(n).Nname), n.X}
|
||||
|
||||
addr := typecheck.NodAddr(clos)
|
||||
addr.SetEsc(n.Esc())
|
||||
@ -198,3 +198,81 @@ func walkMethodValue(n *ir.SelectorExpr, init *ir.Nodes) ir.Node {
|
||||
|
||||
return walkExpr(cfn, init)
|
||||
}
|
||||
|
||||
// methodValueWrapper returns the DCLFUNC node representing the
|
||||
// wrapper function (*-fm) needed for the given method value. If the
|
||||
// wrapper function hasn't already been created yet, it's created and
|
||||
// added to typecheck.Target.Decls.
|
||||
func methodValueWrapper(dot *ir.SelectorExpr) *ir.Func {
|
||||
if dot.Op() != ir.OMETHVALUE {
|
||||
base.Fatalf("methodValueWrapper: unexpected %v (%v)", dot, dot.Op())
|
||||
}
|
||||
|
||||
t0 := dot.Type()
|
||||
meth := dot.Sel
|
||||
rcvrtype := dot.X.Type()
|
||||
sym := ir.MethodSymSuffix(rcvrtype, meth, "-fm")
|
||||
|
||||
if sym.Uniq() {
|
||||
return sym.Def.(*ir.Func)
|
||||
}
|
||||
sym.SetUniq(true)
|
||||
|
||||
savecurfn := ir.CurFunc
|
||||
saveLineNo := base.Pos
|
||||
ir.CurFunc = nil
|
||||
|
||||
// Set line number equal to the line number where the method is declared.
|
||||
if pos := dot.Selection.Pos; pos.IsKnown() {
|
||||
base.Pos = pos
|
||||
}
|
||||
// Note: !dot.Selection.Pos.IsKnown() happens for method expressions where
|
||||
// the method is implicitly declared. The Error method of the
|
||||
// built-in error type is one such method. We leave the line
|
||||
// number at the use of the method expression in this
|
||||
// case. See issue 29389.
|
||||
|
||||
tfn := ir.NewFuncType(base.Pos, nil,
|
||||
typecheck.NewFuncParams(t0.Params(), true),
|
||||
typecheck.NewFuncParams(t0.Results(), false))
|
||||
|
||||
fn := typecheck.DeclFunc(sym, tfn)
|
||||
fn.SetDupok(true)
|
||||
fn.SetNeedctxt(true)
|
||||
fn.SetWrapper(true)
|
||||
|
||||
// Declare and initialize variable holding receiver.
|
||||
ptr := ir.NewNameAt(base.Pos, typecheck.Lookup(".this"))
|
||||
ptr.Class = ir.PAUTOHEAP
|
||||
ptr.SetType(rcvrtype)
|
||||
ptr.Curfn = fn
|
||||
ptr.SetIsClosureVar(true)
|
||||
ptr.SetByval(true)
|
||||
fn.ClosureVars = append(fn.ClosureVars, ptr)
|
||||
|
||||
call := ir.NewCallExpr(base.Pos, ir.OCALL, ir.NewSelectorExpr(base.Pos, ir.OXDOT, ptr, meth), nil)
|
||||
call.Args = ir.ParamNames(tfn.Type())
|
||||
call.IsDDD = tfn.Type().IsVariadic()
|
||||
|
||||
var body ir.Node = call
|
||||
if t0.NumResults() != 0 {
|
||||
ret := ir.NewReturnStmt(base.Pos, nil)
|
||||
ret.Results = []ir.Node{call}
|
||||
body = ret
|
||||
}
|
||||
|
||||
fn.Body = []ir.Node{body}
|
||||
typecheck.FinishFuncBody()
|
||||
|
||||
typecheck.Func(fn)
|
||||
// Need to typecheck the body of the just-generated wrapper.
|
||||
// typecheckslice() requires that Curfn is set when processing an ORETURN.
|
||||
ir.CurFunc = fn
|
||||
typecheck.Stmts(fn.Body)
|
||||
sym.Def = fn
|
||||
typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
|
||||
ir.CurFunc = savecurfn
|
||||
base.Pos = saveLineNo
|
||||
|
||||
return fn
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user