mirror of
https://github.com/golang/go
synced 2024-11-11 23:20:24 -07:00
[dev.regabi] cmd/compile/internal/gc: add MethodName for getting referenced method
A common operation throughout the front end is getting the ONAME for a method used in a method selector, method expression, or method value. This CL adds MethodName as a uniform API for doing this for all of these kinds of nodes. For method selectors (ODOTMETH) and method expressions (ONAMEs where isMethodExpression reports true), we take advantage of the Node.Opt field to save the types.Field. This is the approach we already started taking in golang.org/cl/271217 (caching types.Field in Node.Opt for ODOT). For method values (OCALLPART), we continue using the existing callpartMethod helper function. Escape analysis already uses Node.Opt for tracking the method value's closure's data flow. A subsequent, automated refactoring CL will make more use of this method. For now, we just address a few cases in inl.go that aren't easily automated. Passes toolstash-check. Change-Id: Ic92b288b2d8b2fa7e18e3b68634326b8ef0d869b Reviewed-on: https://go-review.googlesource.com/c/go/+/272387 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
e1047302bd
commit
b30c7a8044
@ -50,7 +50,6 @@ var knownFormats = map[string]string{
|
||||
"*cmd/compile/internal/types.Sym %v": "",
|
||||
"*cmd/compile/internal/types.Type %#L": "",
|
||||
"*cmd/compile/internal/types.Type %#v": "",
|
||||
"*cmd/compile/internal/types.Type %+v": "",
|
||||
"*cmd/compile/internal/types.Type %-S": "",
|
||||
"*cmd/compile/internal/types.Type %0S": "",
|
||||
"*cmd/compile/internal/types.Type %L": "",
|
||||
|
@ -435,6 +435,7 @@ func typecheckpartialcall(fn *Node, sym *types.Sym) {
|
||||
fn.Right = newname(sym)
|
||||
fn.Op = OCALLPART
|
||||
fn.Type = xfunc.Type
|
||||
fn.SetOpt(nil) // clear types.Field from ODOTMETH
|
||||
}
|
||||
|
||||
// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
|
||||
|
@ -358,9 +358,6 @@ func (v *hairyVisitor) visit(n *Node) bool {
|
||||
if t == nil {
|
||||
Fatalf("no function type for [%p] %+v\n", n.Left, n.Left)
|
||||
}
|
||||
if t.Nname() == nil {
|
||||
Fatalf("no function definition for [%p] %+v\n", t, t)
|
||||
}
|
||||
if isRuntimePkg(n.Left.Sym.Pkg) {
|
||||
fn := n.Left.Sym.Name
|
||||
if fn == "heapBits.nextArena" {
|
||||
@ -372,7 +369,7 @@ func (v *hairyVisitor) visit(n *Node) bool {
|
||||
break
|
||||
}
|
||||
}
|
||||
if inlfn := asNode(t.FuncType().Nname).Func; inlfn.Inl != nil {
|
||||
if inlfn := n.Left.MethodName().Func; inlfn.Inl != nil {
|
||||
v.budget -= inlfn.Inl.Cost
|
||||
break
|
||||
}
|
||||
@ -703,11 +700,7 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||
Fatalf("no function type for [%p] %+v\n", n.Left, n.Left)
|
||||
}
|
||||
|
||||
if n.Left.Type.Nname() == nil {
|
||||
Fatalf("no function definition for [%p] %+v\n", n.Left.Type, n.Left.Type)
|
||||
}
|
||||
|
||||
n = mkinlcall(n, asNode(n.Left.Type.FuncType().Nname), maxCost, inlMap)
|
||||
n = mkinlcall(n, n.Left.MethodName(), maxCost, inlMap)
|
||||
}
|
||||
|
||||
lineno = lno
|
||||
|
@ -266,7 +266,11 @@ func (n *Node) Opt() interface{} {
|
||||
// SetOpt sets the optimizer data for the node, which must not have been used with SetVal.
|
||||
// SetOpt(nil) is ignored for Vals to simplify call sites that are clearing Opts.
|
||||
func (n *Node) SetOpt(x interface{}) {
|
||||
if x == nil && n.HasVal() {
|
||||
if x == nil {
|
||||
if n.HasOpt() {
|
||||
n.SetHasOpt(false)
|
||||
n.E = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
if n.HasVal() {
|
||||
|
@ -2416,6 +2416,7 @@ func typecheckMethodExpr(n *Node) (res *Node) {
|
||||
n.Type = methodfunc(m.Type, n.Left.Type)
|
||||
n.Xoffset = 0
|
||||
n.SetClass(PFUNC)
|
||||
n.SetOpt(m)
|
||||
// methodSym already marked n.Sym as a function.
|
||||
|
||||
// Issue 25065. Make sure that we emit the symbol for a local method.
|
||||
@ -2538,6 +2539,7 @@ func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field {
|
||||
n.Xoffset = f2.Offset
|
||||
n.Type = f2.Type
|
||||
n.Op = ODOTMETH
|
||||
n.SetOpt(f2)
|
||||
|
||||
return f2
|
||||
}
|
||||
@ -4017,3 +4019,22 @@ func curpkg() *types.Pkg {
|
||||
|
||||
return fnpkg(fn)
|
||||
}
|
||||
|
||||
// MethodName returns the ONAME representing the method
|
||||
// referenced by expression n, which must be a method selector,
|
||||
// method expression, or method value.
|
||||
func (n *Node) MethodName() *Node {
|
||||
return asNode(n.MethodFunc().Type.Nname())
|
||||
}
|
||||
|
||||
// MethodFunc is like MethodName, but returns the types.Field instead.
|
||||
func (n *Node) MethodFunc() *types.Field {
|
||||
switch {
|
||||
case n.Op == ODOTMETH || n.isMethodExpression():
|
||||
return n.Opt().(*types.Field)
|
||||
case n.Op == OCALLPART:
|
||||
return callpartMethod(n)
|
||||
}
|
||||
Fatalf("unexpected node: %v (%v)", n, n.Op)
|
||||
panic("unreachable")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user