fn := makepartialcall(dot, dot.Type(), sym)
fn.SetWrapper(true)
- return ir.NewCallPartExpr(dot.Pos(), dot.Left(), NewName(sym), fn)
+ return ir.NewCallPartExpr(dot.Pos(), dot.Left(), dot.(*ir.SelectorExpr).Selection, fn)
}
// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
// 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 {
- 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 {
- base.Fatalf("failed to find field for OCALLPART")
- }
-
- return m
+ return n.(*ir.CallPartExpr).Method
}
w.op(ir.OXDOT)
w.pos(n.Pos())
w.expr(n.Left())
- // Right node should be ONAME
- w.selector(n.Right().Sym())
+ w.selector(n.Sym())
case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH:
w.op(ir.OXDOT)
// In any event, let the visitList(n.List()) below take care of the statements,
// and don't charge for the OBLOCK itself. The ++ undoes the -- below.
v.budget++
+
+ case ir.OCALLPART:
+ v.budget-- // Hack for toolstash -cmp.
}
v.budget--
me.SetType(methodfunc(m.Type, n.Left().Type()))
me.SetOffset(0)
me.SetClass(ir.PFUNC)
- me.SetOpt(m)
+ me.(*ir.MethodExpr).Method = m
// Issue 25065. Make sure that we emit the symbol for a local method.
if base.Ctxt.Flag_dynlink && !inimport && (t.Sym() == nil || t.Sym().Pkg == ir.LocalPkg) {
}
n.SetOp(ir.ODOTINTER)
- } else {
- n.SetOpt(f1)
}
-
+ n.(*ir.SelectorExpr).Selection = f1
return f1
}
n.SetOffset(f2.Offset)
n.SetType(f2.Type)
n.SetOp(ir.ODOTMETH)
- n.SetOpt(f2)
+ n.(*ir.SelectorExpr).Selection = f2
return f2
}
// MethodFunc is like MethodName, but returns the types.Field instead.
func methodExprFunc(n ir.Node) *types.Field {
switch n.Op() {
- case ir.ODOTMETH, ir.OMETHEXPR:
- return n.Opt().(*types.Field)
+ case ir.ODOTMETH:
+ return n.(*ir.SelectorExpr).Selection
+ case ir.OMETHEXPR:
+ return n.(*ir.MethodExpr).Method
case ir.OCALLPART:
return callpartMethod(n)
}
if t.IsPtr() {
t = t.Elem()
}
- field := n.Opt().(*types.Field)
+ field := n.(*ir.SelectorExpr).Selection
if field == nil {
base.Fatalf("usefield %v %v without paramfld", n.Left().Type(), n.Sym())
}
miniExpr
fn *Func
X Node
- Method *Name
+ Method *types.Field
}
-func NewCallPartExpr(pos src.XPos, x Node, method *Name, fn *Func) *CallPartExpr {
+func NewCallPartExpr(pos src.XPos, x Node, method *types.Field, fn *Func) *CallPartExpr {
n := &CallPartExpr{fn: fn, X: x, Method: method}
n.op = OCALLPART
n.pos = pos
func (n *CallPartExpr) rawCopy() Node { c := *n; return &c }
func (n *CallPartExpr) Func() *Func { return n.fn }
func (n *CallPartExpr) Left() Node { return n.X }
-func (n *CallPartExpr) Right() Node { return n.Method }
+func (n *CallPartExpr) Sym() *types.Sym { return n.Method.Sym }
func (n *CallPartExpr) SetLeft(x Node) { n.X = x }
-func (n *CallPartExpr) SetRight(x Node) { n.Method = x.(*Name) }
// A ClosureExpr is a function literal expression.
type ClosureExpr struct {
sym *types.Sym
offset int64
class Class
+ Method *types.Field
}
func NewMethodExpr(pos src.XPos, op Op, x, m Node) *MethodExpr {
// A SelectorExpr is a selector expression X.Sym.
type SelectorExpr struct {
miniExpr
- X Node
- Sel *types.Sym
- offset int64
+ X Node
+ Sel *types.Sym
+ offset int64
+ Selection *types.Field
}
func NewSelectorExpr(pos src.XPos, x Node, sel *types.Sym) *SelectorExpr {
case OCALLPART:
exprFmt(n.Left(), s, nprec, mode)
- if n.Right() == nil || n.Right().Sym() == nil {
+ if n.Sym() == nil {
fmt.Fprint(s, ".<nil>")
return
}
- mode.Fprintf(s, ".%0S", n.Right().Sym())
+ mode.Fprintf(s, ".%0S", n.Sym())
case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
exprFmt(n.Left(), s, nprec, mode)