mirror of
https://github.com/golang/go.git
synced 2024-09-21 18:38:37 +00:00
[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:
parent
4eaef981b5
commit
e5c6463e20
@ -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:
|
||||
//
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) }
|
||||
|
@ -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")) }
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user