return walkexpr(clos, init)
}
-func typecheckpartialcall(dot ir.Node, sym *types.Sym) {
+func typecheckpartialcall(dot ir.Node, sym *types.Sym) *ir.CallPartExpr {
switch dot.Op() {
case ir.ODOTINTER, ir.ODOTMETH:
break
fn := makepartialcall(dot, dot.Type(), sym)
fn.SetWrapper(true)
- dot.SetOp(ir.OCALLPART)
- dot.SetRight(NewName(sym))
- dot.SetType(fn.Type())
- dot.SetFunc(fn)
- dot.SetOpt(nil) // clear types.Field from ODOTMETH
+ return ir.NewCallPartExpr(dot.Pos(), dot.Left(), NewName(sym), fn)
}
// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
return t
}
-func walkpartialcall(n ir.Node, init *ir.Nodes) ir.Node {
+func walkpartialcall(n *ir.CallPartExpr, init *ir.Nodes) ir.Node {
// Create closure in the form of a composite literal.
// For x.M with receiver (x) type T, the generated code looks like:
//
// - msym is the method symbol
// - t is function type (with receiver)
// Returns a pointer to the existing or added Field; or nil if there's an error.
-func addmethod(n ir.Node, msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
+func addmethod(n *ir.Func, msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
if msym == nil {
base.Fatalf("no method symbol")
}
}
func isIntrinsicCall(n ir.Node) bool {
- if n == nil || n.Left() == nil {
+ if n == nil {
return false
}
- return findIntrinsic(n.Left().Sym()) != nil
+ name, ok := n.Left().(*ir.Name)
+ if !ok {
+ return false
+ }
+ return findIntrinsic(name.Sym()) != nil
}
// intrinsicCall converts a call to a recognized intrinsic function into the intrinsic SSA operation.
if top&ctxCallee != 0 {
ok |= ctxCallee
} else {
- typecheckpartialcall(n, s)
+ n = typecheckpartialcall(n, s)
ok |= ctxExpr
}
n = walkclosure(n, init)
case ir.OCALLPART:
- n = walkpartialcall(n, init)
+ n = walkpartialcall(n.(*ir.CallPartExpr), init)
}
// Expressions that are constant at run time but not
func (n *ClosureRead) RawCopy() Node { c := *n; return &c }
func (n *ClosureRead) Type() *types.Type { return n.typ }
func (n *ClosureRead) Offset() int64 { return n.offset }
+
+// A CallPartExpr is a method expression X.Method (uncalled).
+type CallPartExpr struct {
+ miniExpr
+ fn *Func
+ X Node
+ Method *Name
+}
+
+func NewCallPartExpr(pos src.XPos, x Node, method *Name, fn *Func) *CallPartExpr {
+ n := &CallPartExpr{fn: fn, X: x, Method: method}
+ n.op = OCALLPART
+ n.pos = pos
+ n.typ = fn.Type()
+ n.fn = fn
+ return n
+}
+
+func (n *CallPartExpr) String() string { return fmt.Sprint(n) }
+func (n *CallPartExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+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) SetLeft(x Node) { n.X = x }
+func (n *CallPartExpr) SetRight(x Node) { n.Method = x.(*Name) }
func (n *miniNode) Type() *types.Type { return nil }
func (n *miniNode) SetType(*types.Type) { panic(n.no("SetType")) }
func (n *miniNode) Func() *Func { return nil }
-func (n *miniNode) SetFunc(*Func) { panic(n.no("SetFunc")) }
func (n *miniNode) Name() *Name { return nil }
func (n *miniNode) Sym() *types.Sym { return nil }
func (n *miniNode) SetSym(*types.Sym) { panic(n.no("SetSym")) }
Type() *types.Type
SetType(t *types.Type)
Func() *Func
- SetFunc(x *Func)
Name() *Name
Sym() *types.Sym
SetSym(x *types.Sym)
typ *types.Type
orig Node // original form, for printing, and tracking copies of ONAMEs
- // func
- fn *Func
-
sym *types.Sym // various
opt interface{}
func (n *node) SetOrig(x Node) { n.orig = x }
func (n *node) Type() *types.Type { return n.typ }
func (n *node) SetType(x *types.Type) { n.typ = x }
-func (n *node) Func() *Func { return n.fn }
-func (n *node) SetFunc(x *Func) { n.fn = x }
+func (n *node) Func() *Func { return nil }
func (n *node) Name() *Name { return nil }
func (n *node) Sym() *types.Sym { return n.sym }
func (n *node) SetSym(x *types.Sym) { n.sym = x }
OCALLFUNC: true,
OCALLINTER: true,
OCALLMETH: true,
- OCALLPART: true,
OCAP: true,
OCASE: true,
OCFUNC: true,
}{
{Func{}, 168, 288},
{Name{}, 128, 224},
- {node{}, 84, 144},
+ {node{}, 80, 136},
}
for _, tt := range tests {