// 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
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() {}
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) {
// 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
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)
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)
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.
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 }()
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
{
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() {
}
})
+ fn.Nname.Defn = fn
target.Funcs = append(target.Funcs, fn)
}
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.
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.
// 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]))
typecheck.Stmts(fnInit.Body)
ir.CurFunc = nil
- typecheck.Target.Funcs = append(typecheck.Target.Funcs, fnInit)
typecheck.Target.Inits = append(typecheck.Target.Inits, fnInit)
}
}
})
fn.SetNilCheckDisabled(true)
- typecheck.Target.Funcs = append(typecheck.Target.Funcs, fn)
return fn
}
// neither of which can be nil, and our comparisons
// are shallow.
fn.SetNilCheckDisabled(true)
- typecheck.Target.Funcs = append(typecheck.Target.Funcs, fn)
return fn
}
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)
ir.CurFunc = fn
typecheck.Stmts(fn.Body)
- typecheck.Target.Funcs = append(typecheck.Target.Funcs, fn)
-
// Restore previous context.
base.Pos = savepos
typecheck.DeclContext = savedclcontext
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
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
}
)
// 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
+func importfunc(s *types.Sym, t *types.Type) {
+ fn := ir.NewFunc(src.NoXPos, src.NoXPos, s, t)
+ importsym(fn.Nname)
}
-// 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
+// importvar declares symbol s as an imported variable with type t.
+func importvar(s *types.Sym, t *types.Type) {
+ n := ir.NewNameAt(src.NoXPos, s, t)
+ n.Class = ir.PEXTERN
+ importsym(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)
+func importsym(name *ir.Name) {
+ sym := name.Sym()
+ if sym.Def != nil {
+ base.Fatalf("importsym of symbol that already exists: %v", sym.Def)
}
-
- n := ir.NewDeclNameAt(pos, op, s)
- n.Class = ctxt // TODO(mdempsky): Move this into NewDeclNameAt too?
- s.SetPkgDef(n)
- return n
-}
-
-// 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)
+ sym.Def = name
}
"cmd/compile/internal/ir"
"cmd/compile/internal/types"
"cmd/internal/obj"
- "cmd/internal/src"
)
func LookupRuntime(name string) *ir.Name {
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)
}
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)
}
// 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) {}
+++ /dev/null
-// 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 }