diff --git a/src/cmd/compile/internal/inline/inl.go b/src/cmd/compile/internal/inline/inl.go index 908d6ca347..19244fbe7f 100644 --- a/src/cmd/compile/internal/inline/inl.go +++ b/src/cmd/compile/internal/inline/inl.go @@ -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 diff --git a/src/cmd/compile/internal/ir/func.go b/src/cmd/compile/internal/ir/func.go index 406c614d19..7efc71d2c7 100644 --- a/src/cmd/compile/internal/ir/func.go +++ b/src/cmd/compile/internal/ir/func.go @@ -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 diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index d71a1fc5fa..59b10b3b33 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -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) } diff --git a/src/cmd/compile/internal/pkginit/init.go b/src/cmd/compile/internal/pkginit/init.go index 4a4bc1f399..4636c740e2 100644 --- a/src/cmd/compile/internal/pkginit/init.go +++ b/src/cmd/compile/internal/pkginit/init.go @@ -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) } } diff --git a/src/cmd/compile/internal/reflectdata/alg.go b/src/cmd/compile/internal/reflectdata/alg.go index a561c1e8b5..edfd92fb40 100644 --- a/src/cmd/compile/internal/reflectdata/alg.go +++ b/src/cmd/compile/internal/reflectdata/alg.go @@ -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 } diff --git a/src/cmd/compile/internal/ssa/export_test.go b/src/cmd/compile/internal/ssa/export_test.go index 53a5b3070b..f02cfd2cd4 100644 --- a/src/cmd/compile/internal/ssa/export_test.go +++ b/src/cmd/compile/internal/ssa/export_test.go @@ -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) diff --git a/src/cmd/compile/internal/ssagen/abi.go b/src/cmd/compile/internal/ssagen/abi.go index f01563e776..a1ed4c124c 100644 --- a/src/cmd/compile/internal/ssagen/abi.go +++ b/src/cmd/compile/internal/ssagen/abi.go @@ -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 diff --git a/src/cmd/compile/internal/typecheck/dcl.go b/src/cmd/compile/internal/typecheck/dcl.go index 9da2c8f324..d0783760f6 100644 --- a/src/cmd/compile/internal/typecheck/dcl.go +++ b/src/cmd/compile/internal/typecheck/dcl.go @@ -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 } diff --git a/src/cmd/compile/internal/typecheck/export.go b/src/cmd/compile/internal/typecheck/export.go index 40cf451d6a..585c1b78c2 100644 --- a/src/cmd/compile/internal/typecheck/export.go +++ b/src/cmd/compile/internal/typecheck/export.go @@ -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 } diff --git a/src/cmd/compile/internal/typecheck/syms.go b/src/cmd/compile/internal/typecheck/syms.go index 55160e47f0..4f75129998 100644 --- a/src/cmd/compile/internal/typecheck/syms.go +++ b/src/cmd/compile/internal/typecheck/syms.go @@ -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) } diff --git a/src/cmd/compile/internal/typecheck/typecheck.go b/src/cmd/compile/internal/typecheck/typecheck.go index a36acb9300..2ab812e548 100644 --- a/src/cmd/compile/internal/typecheck/typecheck.go +++ b/src/cmd/compile/internal/typecheck/typecheck.go @@ -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) {} diff --git a/src/cmd/compile/internal/types/scope.go b/src/cmd/compile/internal/types/scope.go deleted file mode 100644 index 438a3f9a47..0000000000 --- a/src/cmd/compile/internal/types/scope.go +++ /dev/null @@ -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 }