var dictVar *ir.Name
var dictAssign *ir.AssignStmt
if outer != nil {
- dictVar = ir.NewNameAt(pos, typecheck.LookupNum(typecheck.LocalDictName, g.dnum))
- dictVar.SetSym(outer.Sym().Pkg.Lookup(dictVar.Sym().Name))
+ dictVar = ir.NewNameAt(pos, closureSym(outer, typecheck.LocalDictName, g.dnum))
g.dnum++
dictVar.Class = ir.PAUTO
typed(types.Types[types.TUINTPTR], dictVar)
var rcvrVar *ir.Name
var rcvrAssign ir.Node
if rcvrValue != nil {
- rcvrVar = ir.NewNameAt(pos, typecheck.LookupNum(".rcvr", g.dnum))
- if outer != nil {
- rcvrVar.SetSym(outer.Sym().Pkg.Lookup(rcvrVar.Sym().Name))
- }
+ rcvrVar = ir.NewNameAt(pos, closureSym(outer, ".rcvr", g.dnum))
g.dnum++
typed(rcvrValue.Type(), rcvrVar)
rcvrAssign = ir.NewAssignStmt(pos, rcvrVar, rcvrValue)
var formalResults []*types.Field // returns of closure
for i := 0; i < typ.NumParams(); i++ {
t := typ.Params().Field(i).Type
- arg := ir.NewNameAt(pos, typecheck.LookupNum("a", i))
- if outer != nil {
- arg.SetSym(outer.Sym().Pkg.Lookup(arg.Sym().Name))
- }
+ arg := ir.NewNameAt(pos, closureSym(outer, "a", i))
arg.Class = ir.PPARAM
typed(t, arg)
arg.Curfn = fn
}
for i := 0; i < typ.NumResults(); i++ {
t := typ.Results().Field(i).Type
- result := ir.NewNameAt(pos, typecheck.LookupNum("r", i)) // TODO: names not needed?
- if outer != nil {
- result.SetSym(outer.Sym().Pkg.Lookup(result.Sym().Name))
- }
+ result := ir.NewNameAt(pos, closureSym(outer, "r", i)) // TODO: names not needed?
result.Class = ir.PPARAMOUT
typed(t, result)
result.Curfn = fn
}
+// closureSym returns outer.Sym().Pkg.LookupNum(prefix, n).
+// If outer is nil, then types.LocalPkg is used instead.
+func closureSym(outer *ir.Func, prefix string, n int) *types.Sym {
+ pkg := types.LocalPkg
+ if outer != nil {
+ pkg = outer.Sym().Pkg
+ }
+ return pkg.LookupNum(prefix, n)
+}
+
// assertToBound returns a new node that converts a node rcvr with interface type to
// the 'dst' interface type.
func assertToBound(info *instInfo, dictVar *ir.Name, pos src.XPos, rcvr ir.Node, dst *types.Type) ir.Node {
"bytes"
"fmt"
"sort"
- "strconv"
"strings"
"cmd/compile/internal/base"
return assignconvfn(n, t, func() string { return context })
}
-// LookupNum looks up the symbol starting with prefix and ending with
-// the decimal n. If prefix is too long, LookupNum panics.
+// LookupNum returns types.LocalPkg.LookupNum(prefix, n).
func LookupNum(prefix string, n int) *types.Sym {
- var buf [20]byte // plenty long enough for all current users
- copy(buf[:], prefix)
- b := strconv.AppendInt(buf[:len(prefix)], int64(n), 10)
- return types.LocalPkg.LookupBytes(b)
+ return types.LocalPkg.LookupNum(prefix, n)
}
// Given funarg struct list, return list of fn args.
"cmd/internal/objabi"
"fmt"
"sort"
+ "strconv"
"sync"
)
return pkg.Lookup(str)
}
+// LookupNum looks up the symbol starting with prefix and ending with
+// the decimal n. If prefix is too long, LookupNum panics.
+func (pkg *Pkg) LookupNum(prefix string, n int) *Sym {
+ var buf [20]byte // plenty long enough for all current users
+ copy(buf[:], prefix)
+ b := strconv.AppendInt(buf[:len(prefix)], int64(n), 10)
+ return pkg.LookupBytes(b)
+}
+
var (
internedStringsmu sync.Mutex // protects internedStrings
internedStrings = map[string]string{}