mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.regabi] cmd/compile: store types.Field on {Selector,CallPart}Expr
It's useful to have quick access to the types.Field that a given selector or method value expression refer to. Previously we abused Opt for this, but couldn't do that for OCALLPART because escape analysis uses Opt. Now that we have more flexibility, we can simply add additional pointer fields for this. This also allows getting rid of an unneeded ONAME node for OCALLPART. Passes buildall w/ toolstash -cmp. Change-Id: I980d7bdb19abfd0b6f58a232876861b88dee1e47 Reviewed-on: https://go-review.googlesource.com/c/go/+/275034 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org> Trust: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
a2058bac21
commit
351bc2f38c
7 changed files with 24 additions and 32 deletions
|
|
@ -427,7 +427,7 @@ func typecheckpartialcall(dot ir.Node, sym *types.Sym) *ir.CallPartExpr {
|
||||||
fn := makepartialcall(dot, dot.Type(), sym)
|
fn := makepartialcall(dot, dot.Type(), sym)
|
||||||
fn.SetWrapper(true)
|
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
|
// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
|
||||||
|
|
@ -565,16 +565,5 @@ func walkpartialcall(n *ir.CallPartExpr, init *ir.Nodes) ir.Node {
|
||||||
// callpartMethod returns the *types.Field representing the method
|
// callpartMethod returns the *types.Field representing the method
|
||||||
// referenced by method value n.
|
// referenced by method value n.
|
||||||
func callpartMethod(n ir.Node) *types.Field {
|
func callpartMethod(n ir.Node) *types.Field {
|
||||||
if n.Op() != ir.OCALLPART {
|
return n.(*ir.CallPartExpr).Method
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1290,8 +1290,7 @@ func (w *exportWriter) expr(n ir.Node) {
|
||||||
w.op(ir.OXDOT)
|
w.op(ir.OXDOT)
|
||||||
w.pos(n.Pos())
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left())
|
w.expr(n.Left())
|
||||||
// Right node should be ONAME
|
w.selector(n.Sym())
|
||||||
w.selector(n.Right().Sym())
|
|
||||||
|
|
||||||
case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH:
|
case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH:
|
||||||
w.op(ir.OXDOT)
|
w.op(ir.OXDOT)
|
||||||
|
|
|
||||||
|
|
@ -430,6 +430,9 @@ func (v *hairyVisitor) visit(n ir.Node) bool {
|
||||||
// In any event, let the visitList(n.List()) below take care of the statements,
|
// 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.
|
// and don't charge for the OBLOCK itself. The ++ undoes the -- below.
|
||||||
v.budget++
|
v.budget++
|
||||||
|
|
||||||
|
case ir.OCALLPART:
|
||||||
|
v.budget-- // Hack for toolstash -cmp.
|
||||||
}
|
}
|
||||||
|
|
||||||
v.budget--
|
v.budget--
|
||||||
|
|
|
||||||
|
|
@ -2385,7 +2385,7 @@ func typecheckMethodExpr(n ir.Node) (res ir.Node) {
|
||||||
me.SetType(methodfunc(m.Type, n.Left().Type()))
|
me.SetType(methodfunc(m.Type, n.Left().Type()))
|
||||||
me.SetOffset(0)
|
me.SetOffset(0)
|
||||||
me.SetClass(ir.PFUNC)
|
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.
|
// 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) {
|
if base.Ctxt.Flag_dynlink && !inimport && (t.Sym() == nil || t.Sym().Pkg == ir.LocalPkg) {
|
||||||
|
|
@ -2448,10 +2448,8 @@ func lookdot(n ir.Node, t *types.Type, dostrcmp int) *types.Field {
|
||||||
}
|
}
|
||||||
|
|
||||||
n.SetOp(ir.ODOTINTER)
|
n.SetOp(ir.ODOTINTER)
|
||||||
} else {
|
|
||||||
n.SetOpt(f1)
|
|
||||||
}
|
}
|
||||||
|
n.(*ir.SelectorExpr).Selection = f1
|
||||||
return f1
|
return f1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2507,7 +2505,7 @@ func lookdot(n ir.Node, t *types.Type, dostrcmp int) *types.Field {
|
||||||
n.SetOffset(f2.Offset)
|
n.SetOffset(f2.Offset)
|
||||||
n.SetType(f2.Type)
|
n.SetType(f2.Type)
|
||||||
n.SetOp(ir.ODOTMETH)
|
n.SetOp(ir.ODOTMETH)
|
||||||
n.SetOpt(f2)
|
n.(*ir.SelectorExpr).Selection = f2
|
||||||
|
|
||||||
return f2
|
return f2
|
||||||
}
|
}
|
||||||
|
|
@ -3933,8 +3931,10 @@ func methodExprName(n ir.Node) *ir.Name {
|
||||||
// MethodFunc is like MethodName, but returns the types.Field instead.
|
// MethodFunc is like MethodName, but returns the types.Field instead.
|
||||||
func methodExprFunc(n ir.Node) *types.Field {
|
func methodExprFunc(n ir.Node) *types.Field {
|
||||||
switch n.Op() {
|
switch n.Op() {
|
||||||
case ir.ODOTMETH, ir.OMETHEXPR:
|
case ir.ODOTMETH:
|
||||||
return n.Opt().(*types.Field)
|
return n.(*ir.SelectorExpr).Selection
|
||||||
|
case ir.OMETHEXPR:
|
||||||
|
return n.(*ir.MethodExpr).Method
|
||||||
case ir.OCALLPART:
|
case ir.OCALLPART:
|
||||||
return callpartMethod(n)
|
return callpartMethod(n)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3757,7 +3757,7 @@ func usefield(n ir.Node) {
|
||||||
if t.IsPtr() {
|
if t.IsPtr() {
|
||||||
t = t.Elem()
|
t = t.Elem()
|
||||||
}
|
}
|
||||||
field := n.Opt().(*types.Field)
|
field := n.(*ir.SelectorExpr).Selection
|
||||||
if field == nil {
|
if field == nil {
|
||||||
base.Fatalf("usefield %v %v without paramfld", n.Left().Type(), n.Sym())
|
base.Fatalf("usefield %v %v without paramfld", n.Left().Type(), n.Sym())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -205,10 +205,10 @@ type CallPartExpr struct {
|
||||||
miniExpr
|
miniExpr
|
||||||
fn *Func
|
fn *Func
|
||||||
X Node
|
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 := &CallPartExpr{fn: fn, X: x, Method: method}
|
||||||
n.op = OCALLPART
|
n.op = OCALLPART
|
||||||
n.pos = pos
|
n.pos = pos
|
||||||
|
|
@ -222,9 +222,8 @@ 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) rawCopy() Node { c := *n; return &c }
|
||||||
func (n *CallPartExpr) Func() *Func { return n.fn }
|
func (n *CallPartExpr) Func() *Func { return n.fn }
|
||||||
func (n *CallPartExpr) Left() Node { return n.X }
|
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) SetLeft(x Node) { n.X = x }
|
||||||
func (n *CallPartExpr) SetRight(x Node) { n.Method = x.(*Name) }
|
|
||||||
|
|
||||||
// A ClosureExpr is a function literal expression.
|
// A ClosureExpr is a function literal expression.
|
||||||
type ClosureExpr struct {
|
type ClosureExpr struct {
|
||||||
|
|
@ -499,6 +498,7 @@ type MethodExpr struct {
|
||||||
sym *types.Sym
|
sym *types.Sym
|
||||||
offset int64
|
offset int64
|
||||||
class Class
|
class Class
|
||||||
|
Method *types.Field
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMethodExpr(pos src.XPos, op Op, x, m Node) *MethodExpr {
|
func NewMethodExpr(pos src.XPos, op Op, x, m Node) *MethodExpr {
|
||||||
|
|
@ -596,9 +596,10 @@ func (n *ResultExpr) SetOffset(x int64) { n.offset = x }
|
||||||
// A SelectorExpr is a selector expression X.Sym.
|
// A SelectorExpr is a selector expression X.Sym.
|
||||||
type SelectorExpr struct {
|
type SelectorExpr struct {
|
||||||
miniExpr
|
miniExpr
|
||||||
X Node
|
X Node
|
||||||
Sel *types.Sym
|
Sel *types.Sym
|
||||||
offset int64
|
offset int64
|
||||||
|
Selection *types.Field
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSelectorExpr(pos src.XPos, x Node, sel *types.Sym) *SelectorExpr {
|
func NewSelectorExpr(pos src.XPos, x Node, sel *types.Sym) *SelectorExpr {
|
||||||
|
|
|
||||||
|
|
@ -1382,11 +1382,11 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
|
|
||||||
case OCALLPART:
|
case OCALLPART:
|
||||||
exprFmt(n.Left(), s, nprec, mode)
|
exprFmt(n.Left(), s, nprec, mode)
|
||||||
if n.Right() == nil || n.Right().Sym() == nil {
|
if n.Sym() == nil {
|
||||||
fmt.Fprint(s, ".<nil>")
|
fmt.Fprint(s, ".<nil>")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, ".%0S", n.Right().Sym())
|
mode.Fprintf(s, ".%0S", n.Sym())
|
||||||
|
|
||||||
case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
|
case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
|
||||||
exprFmt(n.Left(), s, nprec, mode)
|
exprFmt(n.Left(), s, nprec, mode)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue