[dev.regabi] cmd/compile: add ir.CallPartExpr

Now there are no longer any generic nodes with a non-nil
associated Func, so node.fn can be deleted. Also all manipulation
of func fields is done with concrete types, so Node.SetFunc can be
deleted, along with generic implementations.

Passes buildall w/ toolstash -cmp.

Change-Id: I4fee99870951ec9dc224f146d87b22e2bfe16889
Reviewed-on: https://go-review.googlesource.com/c/go/+/274099
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Russ Cox 2020-11-26 01:05:39 -05:00
parent 4eaef981b5
commit e5c6463e20
9 changed files with 40 additions and 21 deletions

View File

@ -414,7 +414,7 @@ func walkclosure(clo ir.Node, init *ir.Nodes) ir.Node {
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
@ -427,11 +427,7 @@ func typecheckpartialcall(dot ir.Node, sym *types.Sym) {
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
@ -522,7 +518,7 @@ func partialCallType(n ir.Node) *types.Type {
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:
//

View File

@ -795,7 +795,7 @@ func methodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sy
// - 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")
}

View File

@ -4146,10 +4146,14 @@ func findIntrinsic(sym *types.Sym) intrinsicBuilder {
}
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.

View File

@ -964,7 +964,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
if top&ctxCallee != 0 {
ok |= ctxCallee
} else {
typecheckpartialcall(n, s)
n = typecheckpartialcall(n, s)
ok |= ctxExpr
}

View File

@ -1578,7 +1578,7 @@ opswitch:
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

View File

@ -84,3 +84,29 @@ func (n *ClosureRead) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
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) }

View File

@ -128,7 +128,6 @@ func (n *miniNode) SetSubOp(Op) { panic(n.no("SetSubOp")) }
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")) }

View File

@ -56,7 +56,6 @@ type Node interface {
Type() *types.Type
SetType(t *types.Type)
Func() *Func
SetFunc(x *Func)
Name() *Name
Sym() *types.Sym
SetSym(x *types.Sym)
@ -143,9 +142,6 @@ type node struct {
typ *types.Type
orig Node // original form, for printing, and tracking copies of ONAMEs
// func
fn *Func
sym *types.Sym // various
opt interface{}
@ -177,8 +173,7 @@ func (n *node) Orig() Node { return n.orig }
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 }
@ -1156,7 +1151,6 @@ var okForNod = [OEND]bool{
OCALLFUNC: true,
OCALLINTER: true,
OCALLMETH: true,
OCALLPART: true,
OCAP: true,
OCASE: true,
OCFUNC: true,

View File

@ -22,7 +22,7 @@ func TestSizeof(t *testing.T) {
}{
{Func{}, 168, 288},
{Name{}, 128, 224},
{node{}, 84, 144},
{node{}, 80, 136},
}
for _, tt := range tests {