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)
|
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() {
|
switch dot.Op() {
|
||||||
case ir.ODOTINTER, ir.ODOTMETH:
|
case ir.ODOTINTER, ir.ODOTMETH:
|
||||||
break
|
break
|
||||||
@ -427,11 +427,7 @@ func typecheckpartialcall(dot ir.Node, sym *types.Sym) {
|
|||||||
fn := makepartialcall(dot, dot.Type(), sym)
|
fn := makepartialcall(dot, dot.Type(), sym)
|
||||||
fn.SetWrapper(true)
|
fn.SetWrapper(true)
|
||||||
|
|
||||||
dot.SetOp(ir.OCALLPART)
|
return ir.NewCallPartExpr(dot.Pos(), dot.Left(), NewName(sym), fn)
|
||||||
dot.SetRight(NewName(sym))
|
|
||||||
dot.SetType(fn.Type())
|
|
||||||
dot.SetFunc(fn)
|
|
||||||
dot.SetOpt(nil) // clear types.Field from ODOTMETH
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
|
// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
|
||||||
@ -522,7 +518,7 @@ func partialCallType(n ir.Node) *types.Type {
|
|||||||
return t
|
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.
|
// Create closure in the form of a composite literal.
|
||||||
// For x.M with receiver (x) type T, the generated code looks like:
|
// 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
|
// - msym is the method symbol
|
||||||
// - t is function type (with receiver)
|
// - t is function type (with receiver)
|
||||||
// Returns a pointer to the existing or added Field; or nil if there's an error.
|
// 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 {
|
if msym == nil {
|
||||||
base.Fatalf("no method symbol")
|
base.Fatalf("no method symbol")
|
||||||
}
|
}
|
||||||
|
@ -4146,10 +4146,14 @@ func findIntrinsic(sym *types.Sym) intrinsicBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isIntrinsicCall(n ir.Node) bool {
|
func isIntrinsicCall(n ir.Node) bool {
|
||||||
if n == nil || n.Left() == nil {
|
if n == nil {
|
||||||
return false
|
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.
|
// 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 {
|
if top&ctxCallee != 0 {
|
||||||
ok |= ctxCallee
|
ok |= ctxCallee
|
||||||
} else {
|
} else {
|
||||||
typecheckpartialcall(n, s)
|
n = typecheckpartialcall(n, s)
|
||||||
ok |= ctxExpr
|
ok |= ctxExpr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1578,7 +1578,7 @@ opswitch:
|
|||||||
n = walkclosure(n, init)
|
n = walkclosure(n, init)
|
||||||
|
|
||||||
case ir.OCALLPART:
|
case ir.OCALLPART:
|
||||||
n = walkpartialcall(n, init)
|
n = walkpartialcall(n.(*ir.CallPartExpr), init)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expressions that are constant at run time but not
|
// 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) RawCopy() Node { c := *n; return &c }
|
||||||
func (n *ClosureRead) Type() *types.Type { return n.typ }
|
func (n *ClosureRead) Type() *types.Type { return n.typ }
|
||||||
func (n *ClosureRead) Offset() int64 { return n.offset }
|
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) Type() *types.Type { return nil }
|
||||||
func (n *miniNode) SetType(*types.Type) { panic(n.no("SetType")) }
|
func (n *miniNode) SetType(*types.Type) { panic(n.no("SetType")) }
|
||||||
func (n *miniNode) Func() *Func { return nil }
|
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) Name() *Name { return nil }
|
||||||
func (n *miniNode) Sym() *types.Sym { return nil }
|
func (n *miniNode) Sym() *types.Sym { return nil }
|
||||||
func (n *miniNode) SetSym(*types.Sym) { panic(n.no("SetSym")) }
|
func (n *miniNode) SetSym(*types.Sym) { panic(n.no("SetSym")) }
|
||||||
|
@ -56,7 +56,6 @@ type Node interface {
|
|||||||
Type() *types.Type
|
Type() *types.Type
|
||||||
SetType(t *types.Type)
|
SetType(t *types.Type)
|
||||||
Func() *Func
|
Func() *Func
|
||||||
SetFunc(x *Func)
|
|
||||||
Name() *Name
|
Name() *Name
|
||||||
Sym() *types.Sym
|
Sym() *types.Sym
|
||||||
SetSym(x *types.Sym)
|
SetSym(x *types.Sym)
|
||||||
@ -143,9 +142,6 @@ type node struct {
|
|||||||
typ *types.Type
|
typ *types.Type
|
||||||
orig Node // original form, for printing, and tracking copies of ONAMEs
|
orig Node // original form, for printing, and tracking copies of ONAMEs
|
||||||
|
|
||||||
// func
|
|
||||||
fn *Func
|
|
||||||
|
|
||||||
sym *types.Sym // various
|
sym *types.Sym // various
|
||||||
opt interface{}
|
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) SetOrig(x Node) { n.orig = x }
|
||||||
func (n *node) Type() *types.Type { return n.typ }
|
func (n *node) Type() *types.Type { return n.typ }
|
||||||
func (n *node) SetType(x *types.Type) { n.typ = x }
|
func (n *node) SetType(x *types.Type) { n.typ = x }
|
||||||
func (n *node) Func() *Func { return n.fn }
|
func (n *node) Func() *Func { return nil }
|
||||||
func (n *node) SetFunc(x *Func) { n.fn = x }
|
|
||||||
func (n *node) Name() *Name { return nil }
|
func (n *node) Name() *Name { return nil }
|
||||||
func (n *node) Sym() *types.Sym { return n.sym }
|
func (n *node) Sym() *types.Sym { return n.sym }
|
||||||
func (n *node) SetSym(x *types.Sym) { n.sym = x }
|
func (n *node) SetSym(x *types.Sym) { n.sym = x }
|
||||||
@ -1156,7 +1151,6 @@ var okForNod = [OEND]bool{
|
|||||||
OCALLFUNC: true,
|
OCALLFUNC: true,
|
||||||
OCALLINTER: true,
|
OCALLINTER: true,
|
||||||
OCALLMETH: true,
|
OCALLMETH: true,
|
||||||
OCALLPART: true,
|
|
||||||
OCAP: true,
|
OCAP: true,
|
||||||
OCASE: true,
|
OCASE: true,
|
||||||
OCFUNC: true,
|
OCFUNC: true,
|
||||||
|
@ -22,7 +22,7 @@ func TestSizeof(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{Func{}, 168, 288},
|
{Func{}, 168, 288},
|
||||||
{Name{}, 128, 224},
|
{Name{}, 128, 224},
|
||||||
{node{}, 84, 144},
|
{node{}, 80, 136},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
Loading…
Reference in New Issue
Block a user