mirror of
https://github.com/golang/go
synced 2024-10-01 13:44:47 +00:00
cmd/compile: cleanup Func construction
This CL moves more common Func-setup logic into ir.NewFunc. In particular, it now handles constructing the Name and wiring them together, setting the Typecheck bit, and setting Sym.Func. Relatedly, this CL also extends typecheck.DeclFunc to append the function to typecheck.Target.Funcs, so that callers no longer need to do this. Change-Id: Ifa0aded8df0517188eb295d0dccc107af85f1e8a Reviewed-on: https://go-review.googlesource.com/c/go/+/520338 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
5c6fbd2c3e
commit
4e411e7bc4
|
@ -818,9 +818,8 @@ func inlcopy(n ir.Node) ir.Node {
|
|||
// x.Func.Nname.Ntype, x.Func.Dcl, x.Func.ClosureVars, and
|
||||
// x.Func.Body for iexport and local inlining.
|
||||
oldfn := x.Func
|
||||
newfn := ir.NewFunc(oldfn.Pos())
|
||||
newfn := ir.NewFunc(oldfn.Pos(), oldfn.Nname.Pos(), oldfn.Nname.Sym(), oldfn.Nname.Type())
|
||||
m.(*ir.ClosureExpr).Func = newfn
|
||||
newfn.Nname = ir.NewNameAt(oldfn.Nname.Pos(), oldfn.Nname.Sym(), oldfn.Nname.Type())
|
||||
// XXX OK to share fn.Type() ??
|
||||
newfn.Body = inlcopylist(oldfn.Body)
|
||||
// Make shallow copy of the Dcl and ClosureVar slices
|
||||
|
|
|
@ -147,14 +147,29 @@ type WasmImport struct {
|
|||
Name string
|
||||
}
|
||||
|
||||
func NewFunc(pos src.XPos) *Func {
|
||||
f := new(Func)
|
||||
f.pos = pos
|
||||
f.op = ODCLFUNC
|
||||
// NewFunc returns a new Func with the given name and type.
|
||||
//
|
||||
// fpos is the position of the "func" token, and npos is the position
|
||||
// of the name identifier.
|
||||
//
|
||||
// TODO(mdempsky): I suspect there's no need for separate fpos and
|
||||
// npos.
|
||||
func NewFunc(fpos, npos src.XPos, sym *types.Sym, typ *types.Type) *Func {
|
||||
name := NewNameAt(npos, sym, typ)
|
||||
name.Class = PFUNC
|
||||
sym.SetFunc(true)
|
||||
|
||||
fn := &Func{Nname: name}
|
||||
fn.pos = fpos
|
||||
fn.op = ODCLFUNC
|
||||
// Most functions are ABIInternal. The importer or symabis
|
||||
// pass may override this.
|
||||
f.ABI = obj.ABIInternal
|
||||
return f
|
||||
fn.ABI = obj.ABIInternal
|
||||
fn.SetTypecheck(1)
|
||||
|
||||
name.Func = fn
|
||||
|
||||
return fn
|
||||
}
|
||||
|
||||
func (f *Func) isStmt() {}
|
||||
|
@ -318,16 +333,6 @@ func FuncSymName(s *types.Sym) string {
|
|||
return s.Name + "·f"
|
||||
}
|
||||
|
||||
// MarkFunc marks a node as a function.
|
||||
func MarkFunc(n *Name) {
|
||||
if n.Op() != ONAME || n.Class != Pxxx {
|
||||
base.FatalfAt(n.Pos(), "expected ONAME/Pxxx node, got %v (%v/%v)", n, n.Op(), n.Class)
|
||||
}
|
||||
|
||||
n.Class = PFUNC
|
||||
n.Sym().SetFunc(true)
|
||||
}
|
||||
|
||||
// ClosureDebugRuntimeCheck applies boilerplate checks for debug flags
|
||||
// and compiling runtime.
|
||||
func ClosureDebugRuntimeCheck(clo *ClosureExpr) {
|
||||
|
@ -402,24 +407,17 @@ func closureName(outerfn *Func, pos src.XPos) *types.Sym {
|
|||
// outerfn is the enclosing function, if any. The returned function is
|
||||
// appending to pkg.Funcs.
|
||||
func NewClosureFunc(fpos, cpos src.XPos, typ *types.Type, outerfn *Func, pkg *Package) *Func {
|
||||
fn := NewFunc(fpos)
|
||||
fn := NewFunc(fpos, fpos, closureName(outerfn, cpos), typ)
|
||||
fn.SetIsHiddenClosure(outerfn != nil)
|
||||
|
||||
name := NewNameAt(fpos, closureName(outerfn, cpos), typ)
|
||||
MarkFunc(name)
|
||||
name.Func = fn
|
||||
name.Defn = fn
|
||||
fn.Nname = name
|
||||
|
||||
clo := &ClosureExpr{Func: fn}
|
||||
clo.op = OCLOSURE
|
||||
clo.pos = cpos
|
||||
fn.OClosure = clo
|
||||
|
||||
fn.SetTypecheck(1)
|
||||
clo.SetType(typ)
|
||||
clo.SetTypecheck(1)
|
||||
fn.OClosure = clo
|
||||
|
||||
fn.Nname.Defn = fn
|
||||
pkg.Funcs = append(pkg.Funcs, fn)
|
||||
|
||||
return fn
|
||||
|
|
|
@ -750,12 +750,22 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index, implicits, explicits []*types.Typ
|
|||
if sym.Name == "init" {
|
||||
sym = Renameinit()
|
||||
}
|
||||
name := do(ir.ONAME, true)
|
||||
setType(name, r.signature(nil))
|
||||
|
||||
name.Func = ir.NewFunc(r.pos())
|
||||
name.Func.Nname = name
|
||||
name.Func.SetTypecheck(1)
|
||||
npos := r.pos()
|
||||
setBasePos(npos)
|
||||
r.typeParamNames()
|
||||
typ := r.signature(nil)
|
||||
fpos := r.pos()
|
||||
|
||||
fn := ir.NewFunc(fpos, npos, sym, typ)
|
||||
name := fn.Nname
|
||||
if !sym.IsBlank() {
|
||||
if sym.Def != nil {
|
||||
base.FatalfAt(name.Pos(), "already have a definition for %v", name)
|
||||
}
|
||||
assert(sym.Def == nil)
|
||||
sym.Def = name
|
||||
}
|
||||
|
||||
if r.hasTypeParams() {
|
||||
name.Func.SetDupok(true)
|
||||
|
@ -990,17 +1000,15 @@ func (r *reader) typeParamNames() {
|
|||
|
||||
func (r *reader) method(rext *reader) *types.Field {
|
||||
r.Sync(pkgbits.SyncMethod)
|
||||
pos := r.pos()
|
||||
npos := r.pos()
|
||||
_, sym := r.selector()
|
||||
r.typeParamNames()
|
||||
_, recv := r.param()
|
||||
typ := r.signature(recv)
|
||||
|
||||
name := ir.NewNameAt(pos, ir.MethodSym(recv.Type, sym), typ)
|
||||
|
||||
name.Func = ir.NewFunc(r.pos())
|
||||
name.Func.Nname = name
|
||||
name.Func.SetTypecheck(1)
|
||||
fpos := r.pos()
|
||||
fn := ir.NewFunc(fpos, npos, ir.MethodSym(recv.Type, sym), typ)
|
||||
name := fn.Nname
|
||||
|
||||
if r.hasTypeParams() {
|
||||
name.Func.SetDupok(true)
|
||||
|
@ -1062,9 +1070,6 @@ func (dict *readerDict) hasTypeParams() bool {
|
|||
func (r *reader) funcExt(name *ir.Name, method *types.Sym) {
|
||||
r.Sync(pkgbits.SyncFuncExt)
|
||||
|
||||
name.Class = 0 // so MarkFunc doesn't complain
|
||||
ir.MarkFunc(name)
|
||||
|
||||
fn := name.Func
|
||||
|
||||
// XXX: Workaround because linker doesn't know how to copy Pos.
|
||||
|
@ -3447,9 +3452,7 @@ func unifiedInlineCall(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.Inlined
|
|||
r := pri.asReader(pkgbits.RelocBody, pkgbits.SyncFuncBody)
|
||||
|
||||
// TODO(mdempsky): This still feels clumsy. Can we do better?
|
||||
tmpfn := ir.NewFunc(fn.Pos())
|
||||
tmpfn.Nname = ir.NewNameAt(fn.Nname.Pos(), callerfn.Sym(), fn.Type())
|
||||
tmpfn.SetTypecheck(1)
|
||||
tmpfn := ir.NewFunc(fn.Pos(), fn.Nname.Pos(), callerfn.Sym(), fn.Type())
|
||||
tmpfn.Closgen = callerfn.Closgen
|
||||
defer func() { callerfn.Closgen = tmpfn.Closgen }()
|
||||
|
||||
|
@ -3623,9 +3626,7 @@ func expandInline(fn *ir.Func, pri pkgReaderIndex) {
|
|||
fndcls := len(fn.Dcl)
|
||||
topdcls := len(typecheck.Target.Funcs)
|
||||
|
||||
tmpfn := ir.NewFunc(fn.Pos())
|
||||
tmpfn.Nname = ir.NewNameAt(fn.Nname.Pos(), fn.Sym(), fn.Type())
|
||||
tmpfn.SetTypecheck(1)
|
||||
tmpfn := ir.NewFunc(fn.Pos(), fn.Nname.Pos(), fn.Sym(), fn.Type())
|
||||
tmpfn.ClosureVars = fn.ClosureVars
|
||||
|
||||
{
|
||||
|
@ -3860,18 +3861,9 @@ func wrapMethodValue(recvType *types.Type, method *types.Field, target *ir.Packa
|
|||
func newWrapperFunc(pos src.XPos, sym *types.Sym, wrapper *types.Type, method *types.Field) *ir.Func {
|
||||
sig := newWrapperType(wrapper, method)
|
||||
|
||||
fn := ir.NewFunc(pos)
|
||||
fn := ir.NewFunc(pos, pos, sym, sig)
|
||||
fn.SetDupok(true) // TODO(mdempsky): Leave unset for local, non-generic wrappers?
|
||||
|
||||
name := ir.NewNameAt(pos, sym, sig)
|
||||
ir.MarkFunc(name)
|
||||
name.Func = fn
|
||||
name.Defn = fn
|
||||
fn.Nname = name
|
||||
|
||||
setType(name, sig)
|
||||
fn.SetTypecheck(1)
|
||||
|
||||
// TODO(mdempsky): De-duplicate with similar logic in funcargs.
|
||||
defParams := func(class ir.Class, params *types.Type) {
|
||||
for _, param := range params.FieldSlice() {
|
||||
|
@ -3909,6 +3901,7 @@ func finishWrapperFunc(fn *ir.Func, target *ir.Package) {
|
|||
}
|
||||
})
|
||||
|
||||
fn.Nname.Defn = fn
|
||||
target.Funcs = append(target.Funcs, fn)
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,7 @@ func MakeInit() {
|
|||
fn.SetIsPackageInit(true)
|
||||
|
||||
// Outline (if legal/profitable) global map inits.
|
||||
newfuncs := []*ir.Func{}
|
||||
nf, newfuncs = staticinit.OutlineMapInits(nf)
|
||||
nf, newfuncs := staticinit.OutlineMapInits(nf)
|
||||
|
||||
// Suppress useless "can inline" diagnostics.
|
||||
// Init functions are only called dynamically.
|
||||
|
@ -55,17 +54,10 @@ func MakeInit() {
|
|||
ir.WithFunc(fn, func() {
|
||||
typecheck.Stmts(nf)
|
||||
})
|
||||
typecheck.Target.Funcs = append(typecheck.Target.Funcs, fn)
|
||||
if base.Debug.WrapGlobalMapDbg > 1 {
|
||||
fmt.Fprintf(os.Stderr, "=-= len(newfuncs) is %d for %v\n",
|
||||
len(newfuncs), fn)
|
||||
}
|
||||
for _, nfn := range newfuncs {
|
||||
if base.Debug.WrapGlobalMapDbg > 1 {
|
||||
fmt.Fprintf(os.Stderr, "=-= add to target.decls %v\n", nfn)
|
||||
}
|
||||
typecheck.Target.Funcs = append(typecheck.Target.Funcs, nfn)
|
||||
}
|
||||
|
||||
// Prepend to Inits, so it runs first, before any user-declared init
|
||||
// functions.
|
||||
|
@ -131,13 +123,14 @@ func MakeTask() {
|
|||
|
||||
// Call runtime.asanregisterglobals function to poison redzones.
|
||||
// runtime.asanregisterglobals(unsafe.Pointer(&globals[0]), ni)
|
||||
asanf := ir.NewNameAt(base.Pos, ir.Pkgs.Runtime.Lookup("asanregisterglobals"),
|
||||
//
|
||||
// TODO(mdempsky): Move into typecheck builtins.
|
||||
asanf := ir.NewFunc(src.NoXPos, src.NoXPos, ir.Pkgs.Runtime.Lookup("asanregisterglobals"),
|
||||
types.NewSignature(nil, []*types.Field{
|
||||
types.NewField(base.Pos, nil, types.Types[types.TUNSAFEPTR]),
|
||||
types.NewField(base.Pos, nil, types.Types[types.TUINTPTR]),
|
||||
}, nil))
|
||||
ir.MarkFunc(asanf)
|
||||
asancall := ir.NewCallExpr(base.Pos, ir.OCALL, asanf, nil)
|
||||
asancall := ir.NewCallExpr(base.Pos, ir.OCALL, asanf.Nname, nil)
|
||||
asancall.Args.Append(typecheck.ConvNop(typecheck.NodAddr(
|
||||
ir.NewIndexExpr(base.Pos, globals, ir.NewInt(base.Pos, 0))), types.Types[types.TUNSAFEPTR]))
|
||||
asancall.Args.Append(typecheck.DefaultLit(ir.NewInt(base.Pos, int64(ni)), types.Types[types.TUINTPTR]))
|
||||
|
@ -148,7 +141,6 @@ func MakeTask() {
|
|||
typecheck.Stmts(fnInit.Body)
|
||||
ir.CurFunc = nil
|
||||
|
||||
typecheck.Target.Funcs = append(typecheck.Target.Funcs, fnInit)
|
||||
typecheck.Target.Inits = append(typecheck.Target.Inits, fnInit)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -243,7 +243,6 @@ func hashFunc(t *types.Type) *ir.Func {
|
|||
})
|
||||
|
||||
fn.SetNilCheckDisabled(true)
|
||||
typecheck.Target.Funcs = append(typecheck.Target.Funcs, fn)
|
||||
|
||||
return fn
|
||||
}
|
||||
|
@ -632,7 +631,6 @@ func eqFunc(t *types.Type) *ir.Func {
|
|||
// neither of which can be nil, and our comparisons
|
||||
// are shallow.
|
||||
fn.SetNilCheckDisabled(true)
|
||||
typecheck.Target.Funcs = append(typecheck.Target.Funcs, fn)
|
||||
return fn
|
||||
}
|
||||
|
||||
|
|
|
@ -55,8 +55,7 @@ type Conf struct {
|
|||
|
||||
func (c *Conf) Frontend() Frontend {
|
||||
if c.fe == nil {
|
||||
f := ir.NewFunc(src.NoXPos)
|
||||
f.Nname = ir.NewNameAt(f.Pos(), &types.Sym{
|
||||
f := ir.NewFunc(src.NoXPos, src.NoXPos, &types.Sym{
|
||||
Pkg: types.NewPkg("my/import/path", "path"),
|
||||
Name: "function",
|
||||
}, nil)
|
||||
|
|
|
@ -327,8 +327,6 @@ func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) {
|
|||
ir.CurFunc = fn
|
||||
typecheck.Stmts(fn.Body)
|
||||
|
||||
typecheck.Target.Funcs = append(typecheck.Target.Funcs, fn)
|
||||
|
||||
// Restore previous context.
|
||||
base.Pos = savepos
|
||||
typecheck.DeclContext = savedclcontext
|
||||
|
|
|
@ -18,11 +18,7 @@ import (
|
|||
var DeclContext ir.Class = ir.PEXTERN // PEXTERN/PAUTO
|
||||
|
||||
func DeclFunc(sym *types.Sym, recv *ir.Field, params, results []*ir.Field) *ir.Func {
|
||||
fn := ir.NewFunc(base.Pos)
|
||||
fn.Nname = ir.NewNameAt(base.Pos, sym, nil)
|
||||
fn.Nname.Func = fn
|
||||
fn.Nname.Defn = fn
|
||||
ir.MarkFunc(fn.Nname)
|
||||
fn := ir.NewFunc(base.Pos, base.Pos, sym, nil)
|
||||
StartFuncBody(fn)
|
||||
|
||||
var recv1 *types.Field
|
||||
|
@ -32,9 +28,12 @@ func DeclFunc(sym *types.Sym, recv *ir.Field, params, results []*ir.Field) *ir.F
|
|||
|
||||
typ := types.NewSignature(recv1, declareParams(fn, ir.PPARAM, params), declareParams(fn, ir.PPARAMOUT, results))
|
||||
checkdupfields("argument", typ.Recvs().FieldSlice(), typ.Params().FieldSlice(), typ.Results().FieldSlice())
|
||||
|
||||
fn.Nname.SetType(typ)
|
||||
fn.Nname.SetTypecheck(1)
|
||||
fn.SetTypecheck(1)
|
||||
|
||||
fn.Nname.Defn = fn
|
||||
Target.Funcs = append(Target.Funcs, fn)
|
||||
|
||||
return fn
|
||||
}
|
||||
|
|
|
@ -12,38 +12,22 @@ import (
|
|||
)
|
||||
|
||||
// importfunc declares symbol s as an imported function with type t.
|
||||
// ipkg is the package being imported.
|
||||
func importfunc(pos src.XPos, s *types.Sym, t *types.Type) *ir.Name {
|
||||
n := importobj(pos, s, ir.ONAME, ir.PFUNC, t)
|
||||
n.Func = ir.NewFunc(pos)
|
||||
n.Func.Nname = n
|
||||
return n
|
||||
}
|
||||
|
||||
// importobj declares symbol s as an imported object representable by op.
|
||||
// ipkg is the package being imported.
|
||||
func importobj(pos src.XPos, s *types.Sym, op ir.Op, ctxt ir.Class, t *types.Type) *ir.Name {
|
||||
n := importsym(pos, s, op, ctxt)
|
||||
n.SetType(t)
|
||||
if ctxt == ir.PFUNC {
|
||||
n.Sym().SetFunc(true)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func importsym(pos src.XPos, s *types.Sym, op ir.Op, ctxt ir.Class) *ir.Name {
|
||||
if n := s.PkgDef(); n != nil {
|
||||
base.Fatalf("importsym of symbol that already exists: %v", n)
|
||||
}
|
||||
|
||||
n := ir.NewDeclNameAt(pos, op, s)
|
||||
n.Class = ctxt // TODO(mdempsky): Move this into NewDeclNameAt too?
|
||||
s.SetPkgDef(n)
|
||||
return n
|
||||
func importfunc(s *types.Sym, t *types.Type) {
|
||||
fn := ir.NewFunc(src.NoXPos, src.NoXPos, s, t)
|
||||
importsym(fn.Nname)
|
||||
}
|
||||
|
||||
// importvar declares symbol s as an imported variable with type t.
|
||||
// ipkg is the package being imported.
|
||||
func importvar(pos src.XPos, s *types.Sym, t *types.Type) *ir.Name {
|
||||
return importobj(pos, s, ir.ONAME, ir.PEXTERN, t)
|
||||
func importvar(s *types.Sym, t *types.Type) {
|
||||
n := ir.NewNameAt(src.NoXPos, s, t)
|
||||
n.Class = ir.PEXTERN
|
||||
importsym(n)
|
||||
}
|
||||
|
||||
func importsym(name *ir.Name) {
|
||||
sym := name.Sym()
|
||||
if sym.Def != nil {
|
||||
base.Fatalf("importsym of symbol that already exists: %v", sym.Def)
|
||||
}
|
||||
sym.Def = name
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"cmd/compile/internal/ir"
|
||||
"cmd/compile/internal/types"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/src"
|
||||
)
|
||||
|
||||
func LookupRuntime(name string) *ir.Name {
|
||||
|
@ -74,9 +73,9 @@ func InitRuntime() {
|
|||
typ := typs[d.typ]
|
||||
switch d.tag {
|
||||
case funcTag:
|
||||
importfunc(src.NoXPos, sym, typ)
|
||||
importfunc(sym, typ)
|
||||
case varTag:
|
||||
importvar(src.NoXPos, sym, typ)
|
||||
importvar(sym, typ)
|
||||
default:
|
||||
base.Fatalf("unhandled declaration tag %v", d.tag)
|
||||
}
|
||||
|
@ -110,9 +109,9 @@ func InitCoverage() {
|
|||
typ := typs[d.typ]
|
||||
switch d.tag {
|
||||
case funcTag:
|
||||
importfunc(src.NoXPos, sym, typ)
|
||||
importfunc(sym, typ)
|
||||
case varTag:
|
||||
importvar(src.NoXPos, sym, typ)
|
||||
importvar(sym, typ)
|
||||
default:
|
||||
base.Fatalf("unhandled declaration tag %v", d.tag)
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
|
||||
// Function collecting autotmps generated during typechecking,
|
||||
// to be included in the package-level init function.
|
||||
var InitTodoFunc = ir.NewFunc(base.Pos)
|
||||
var InitTodoFunc = ir.NewFunc(base.Pos, base.Pos, Lookup("$InitTodo"), types.NewSignature(nil, nil, nil))
|
||||
|
||||
var (
|
||||
NeedRuntimeType = func(*types.Type) {}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package types
|
||||
|
||||
// PkgDef returns the definition associated with s at package scope.
|
||||
func (s *Sym) PkgDef() Object { return s.Def }
|
||||
|
||||
// SetPkgDef sets the definition associated with s at package scope.
|
||||
func (s *Sym) SetPkgDef(n Object) { s.Def = n }
|
Loading…
Reference in a new issue