sig := call.X.Type()
for _, ret := range sig.Results().FieldSlice() {
- retvars = append(retvars, typecheck.Temp(ret.Type))
+ retvars = append(retvars, typecheck.TempAt(base.Pos, ir.CurFunc, ret.Type))
}
sel := call.X.(*ir.SelectorExpr)
// recv must be first in the assignment list as its side effects must
// be ordered before argument side effects.
var lhs, rhs []ir.Node
- recv := typecheck.Temp(sel.X.Type())
+ recv := typecheck.TempAt(base.Pos, ir.CurFunc, sel.X.Type())
lhs = append(lhs, recv)
rhs = append(rhs, sel.X)
// such as labels (possible in InlinedCall nodes).
args := call.Args.Take()
for _, arg := range args {
- argvar := typecheck.Temp(arg.Type())
+ argvar := typecheck.TempAt(base.Pos, ir.CurFunc, arg.Type())
lhs = append(lhs, argvar)
rhs = append(rhs, arg)
argvars := append([]ir.Node(nil), lhs[1:]...)
call.Args = argvars
- tmpnode := typecheck.Temp(concretetyp)
- tmpok := typecheck.Temp(types.Types[types.TBOOL])
+ tmpnode := typecheck.TempAt(base.Pos, ir.CurFunc, concretetyp)
+ tmpok := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TBOOL])
assert := ir.NewTypeAssertExpr(pos, recv, concretetyp)
if base.LoopVarHash.MatchPos(n.Pos(), desc) {
// Rename the loop key, prefix body with assignment from loop key
transformed = append(transformed, VarAndLoop{n, x, lastPos})
- tk := typecheck.Temp(n.Type())
+ tk := typecheck.TempAt(base.Pos, ir.CurFunc, n.Type())
tk.SetTypecheck(1)
as := ir.NewAssignStmt(x.Pos(), n, tk)
as.Def = true
for _, z := range leaked {
transformed = append(transformed, VarAndLoop{z, x, lastPos})
- tz := typecheck.Temp(z.Type())
+ tz := typecheck.TempAt(base.Pos, ir.CurFunc, z.Type())
tz.SetTypecheck(1)
zPrimeForZ[z] = tz
// body' = prebody +
// (6) if tmp_first {tmp_first = false} else {Post} +
// if !cond {break} + ...
- tmpFirst := typecheck.Temp(types.Types[types.TBOOL])
+ tmpFirst := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TBOOL])
// tmpFirstAssign assigns val to tmpFirst
tmpFirstAssign := func(val bool) *ir.AssignStmt {
hashel := hashfor(t.Elem())
// for i := 0; i < nelem; i++
- ni := typecheck.Temp(types.Types[types.TINT])
+ ni := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
init := ir.NewAssignStmt(base.Pos, ni, ir.NewInt(base.Pos, 0))
cond := ir.NewBinaryExpr(base.Pos, ir.OLT, ni, ir.NewInt(base.Pos, t.NumElem()))
post := ir.NewAssignStmt(base.Pos, ni, ir.NewBinaryExpr(base.Pos, ir.OADD, ni, ir.NewInt(base.Pos, 1)))
if iterateTo > 0 {
// Generate an unrolled for loop.
// for i := 0; i < nelem/unroll*unroll; i += unroll
- i := typecheck.Temp(types.Types[types.TINT])
+ i := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
init := ir.NewAssignStmt(base.Pos, i, ir.NewInt(base.Pos, 0))
cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, ir.NewInt(base.Pos, iterateTo))
loop := ir.NewForStmt(base.Pos, nil, cond, nil, nil, false)
return f
}
-func Temp(t *types.Type) *ir.Name {
- return TempAt(base.Pos, ir.CurFunc, t)
-}
-
// make a new Node off the books.
func TempAt(pos src.XPos, curfn *ir.Func, t *types.Type) *ir.Name {
if curfn == nil {
base.Fatalf("no curfn for TempAt")
}
- if curfn.Op() == ir.OCLOSURE {
- ir.Dump("TempAt", curfn)
- base.Fatalf("adding TempAt to wrong closure function")
- }
if t == nil {
base.Fatalf("TempAt called with nil type")
}
ir.CurFunc = InitTodoFunc
}
- tmp := Temp((*np).Type())
+ tmp := TempAt(base.Pos, ir.CurFunc, (*np).Type())
as := ir.NewAssignStmt(base.Pos, tmp, *np)
as.PtrInit().Append(Stmt(ir.NewDecl(n.Pos(), ir.ODCL, tmp)))
*np = tmp
results := call.Type().FieldSlice()
list := make([]ir.Node, len(results))
for i, result := range results {
- tmp := Temp(result.Type)
+ tmp := TempAt(base.Pos, ir.CurFunc, result.Type)
as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, tmp))
as.Lhs.Append(tmp)
list[i] = tmp
return walkExpr(typecheck.Stmt(n), init)
}
- var_ := typecheck.Temp(types.NewPtr(t.Elem()))
+ var_ := typecheck.TempAt(base.Pos, ir.CurFunc, types.NewPtr(t.Elem()))
var_.SetTypecheck(1)
var_.MarkNonNil() // mapaccess always returns a non-nil pointer
var nodes ir.Nodes
// var s []T
- s := typecheck.Temp(l1.Type())
+ s := typecheck.TempAt(base.Pos, ir.CurFunc, l1.Type())
nodes.Append(ir.NewAssignStmt(base.Pos, s, l1)) // s = l1
elemtype := s.Type().Elem()
num := ir.NewUnaryExpr(base.Pos, ir.OLEN, l2)
// newLen := oldLen + num
- newLen := typecheck.Temp(types.Types[types.TINT])
+ newLen := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
nodes.Append(ir.NewAssignStmt(base.Pos, newLen, ir.NewBinaryExpr(base.Pos, ir.OADD, oldLen, num)))
// if uint(newLen) <= uint(oldCap)
nodes = append(nodes, nifneg)
// s := l1
- s := typecheck.Temp(l1.Type())
+ s := typecheck.TempAt(base.Pos, ir.CurFunc, l1.Type())
nodes = append(nodes, ir.NewAssignStmt(base.Pos, s, l1))
elemtype := s.Type().Elem()
// n := s.len + l2
- nn := typecheck.Temp(types.Types[types.TINT])
+ nn := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
nodes = append(nodes, ir.NewAssignStmt(base.Pos, nn, ir.NewBinaryExpr(base.Pos, ir.OADD, ir.NewUnaryExpr(base.Pos, ir.OLEN, s), l2)))
// if uint(n) <= uint(s.cap)
var l []ir.Node
// s = slice to append to
- s := typecheck.Temp(nsrc.Type())
+ s := typecheck.TempAt(base.Pos, ir.CurFunc, nsrc.Type())
l = append(l, ir.NewAssignStmt(base.Pos, s, nsrc))
// num = number of things to append
num := ir.NewInt(base.Pos, int64(argc))
// newLen := s.len + num
- newLen := typecheck.Temp(types.Types[types.TINT])
+ newLen := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
l = append(l, ir.NewAssignStmt(base.Pos, newLen, ir.NewBinaryExpr(base.Pos, ir.OADD, ir.NewUnaryExpr(base.Pos, ir.OLEN, s), num)))
// if uint(newLen) <= uint(s.cap)
n.X = walkExpr(n.X, init)
n.Y = walkExpr(n.Y, init)
- nl := typecheck.Temp(n.X.Type())
- nr := typecheck.Temp(n.Y.Type())
+ nl := typecheck.TempAt(base.Pos, ir.CurFunc, n.X.Type())
+ nr := typecheck.TempAt(base.Pos, ir.CurFunc, n.Y.Type())
var l []ir.Node
l = append(l, ir.NewAssignStmt(base.Pos, nl, n.X))
l = append(l, ir.NewAssignStmt(base.Pos, nr, n.Y))
nfrm := ir.NewUnaryExpr(base.Pos, ir.OSPTR, nr)
nto := ir.NewUnaryExpr(base.Pos, ir.OSPTR, nl)
- nlen := typecheck.Temp(types.Types[types.TINT])
+ nlen := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
// n = len(to)
l = append(l, ir.NewAssignStmt(base.Pos, nlen, ir.NewUnaryExpr(base.Pos, ir.OLEN, nl)))
fn := typecheck.LookupRuntime("memmove")
fn = typecheck.SubstArgTypes(fn, nl.Type().Elem(), nl.Type().Elem())
- nwid := ir.Node(typecheck.Temp(types.Types[types.TUINTPTR]))
+ nwid := ir.Node(typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TUINTPTR]))
setwid := ir.NewAssignStmt(base.Pos, nwid, typecheck.Conv(nlen, types.Types[types.TUINTPTR]))
ne.Body.Append(setwid)
nwid = ir.NewBinaryExpr(base.Pos, ir.OMUL, nwid, ir.NewInt(base.Pos, nl.Type().Elem().Size()))
init.Append(typecheck.Stmt(nif))
t = types.NewArray(t.Elem(), i) // [r]T
- var_ := typecheck.Temp(t)
+ var_ := typecheck.TempAt(base.Pos, ir.CurFunc, t)
appendWalkStmt(init, ir.NewAssignStmt(base.Pos, var_, nil)) // zero temp
r := ir.NewSliceExpr(base.Pos, ir.OSLICE, var_, nil, l, nil) // arr[:l]
// The conv is necessary in case n.Type is named.
ptr.MarkNonNil()
sh := ir.NewSliceHeaderExpr(base.Pos, t, ptr, length, length)
- s := typecheck.Temp(t)
+ s := typecheck.TempAt(base.Pos, ir.CurFunc, t)
r := typecheck.Stmt(ir.NewAssignStmt(base.Pos, s, sh))
r = walkExpr(r, init)
init.Append(r)
}
// mem, overflow := runtime.mulUintptr(et.size, len)
- mem := typecheck.Temp(types.Types[types.TUINTPTR])
- overflow := typecheck.Temp(types.Types[types.TBOOL])
+ mem := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TUINTPTR])
+ overflow := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TBOOL])
fn := typecheck.LookupRuntime("mulUintptr")
call := mkcall1(fn, fn.Type().Results(), init, ir.NewInt(base.Pos, sliceType.Elem().Size()), typecheck.Conv(typecheck.Conv(len, lenType), types.Types[types.TUINTPTR]))
appendWalkStmt(init, ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{mem, overflow}, []ir.Node{call}))
fixedlit(inInitFunction, initKindStatic, n, vstat, init)
return typecheck.Expr(vstat)
}
- var_ := typecheck.Temp(n.Type())
+ var_ := typecheck.TempAt(base.Pos, ir.CurFunc, n.Type())
anylit(n, var_, init)
return var_
}
}
// make new auto *array (3 declare)
- vauto := typecheck.Temp(types.NewPtr(t))
+ vauto := typecheck.TempAt(base.Pos, ir.CurFunc, types.NewPtr(t))
// set auto to point at new temp or heap (3 assign)
var a ir.Node
}
a = initStackTemp(init, x, vstat)
} else if n.Esc() == ir.EscNone {
- a = initStackTemp(init, typecheck.Temp(t), vstat)
+ a = initStackTemp(init, typecheck.TempAt(base.Pos, ir.CurFunc, t), vstat)
} else {
a = ir.NewUnaryExpr(base.Pos, ir.ONEW, ir.TypeNode(t))
}
// for i = 0; i < len(vstatk); i++ {
// map[vstatk[i]] = vstate[i]
// }
- i := typecheck.Temp(types.Types[types.TINT])
+ i := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
rhs := ir.NewIndexExpr(base.Pos, vstate, i)
rhs.SetBounded(true)
// Use temporaries so that mapassign1 can have addressable key, elem.
// TODO(josharian): avoid map key temporaries for mapfast_* assignments with literal keys.
// TODO(khr): assign these temps in order phase so we can reuse them across multiple maplits?
- tmpkey := typecheck.Temp(m.Type().Key())
- tmpelem := typecheck.Temp(m.Type().Elem())
+ tmpkey := typecheck.TempAt(base.Pos, ir.CurFunc, m.Type().Key())
+ tmpelem := typecheck.TempAt(base.Pos, ir.CurFunc, m.Type().Elem())
for _, r := range entries {
r := r.(*ir.KeyExpr)
}
// Evaluate the input interface.
- c := typecheck.Temp(fromType)
+ c := typecheck.TempAt(base.Pos, ir.CurFunc, fromType)
init.Append(ir.NewAssignStmt(base.Pos, c, n.X))
// Grab its parts.
// if res != nil {
// res = res.type
// }
- typeWord = typecheck.Temp(types.NewPtr(types.Types[types.TUINT8]))
+ typeWord = typecheck.TempAt(base.Pos, ir.CurFunc, types.NewPtr(types.Types[types.TUINT8]))
init.Append(ir.NewAssignStmt(base.Pos, typeWord, typecheck.Conv(typecheck.Conv(itab, types.Types[types.TUNSAFEPTR]), typeWord.Type())))
nif := ir.NewIfStmt(base.Pos, typecheck.Expr(ir.NewBinaryExpr(base.Pos, ir.ONE, typeWord, typecheck.NodNil())), nil, nil)
nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, typeWord, itabType(typeWord))}
value = n
case conv.Esc() == ir.EscNone && fromType.Size() <= 1024:
// n does not escape. Use a stack temporary initialized to n.
- value = typecheck.Temp(fromType)
+ value = typecheck.TempAt(base.Pos, ir.CurFunc, fromType)
init.Append(typecheck.Stmt(ir.NewAssignStmt(base.Pos, value, n)))
}
if value != nil {
a.SetTypecheck(1)
a.MarkNonNil()
}
- p := typecheck.Temp(t.PtrTo()) // *[n]byte
+ p := typecheck.TempAt(base.Pos, ir.CurFunc, t.PtrTo()) // *[n]byte
init.Append(typecheck.Stmt(ir.NewAssignStmt(base.Pos, p, a)))
// Copy from the static string data to the [n]byte.
case n.Type().IsStruct():
if n.Type().Field(0).Sym.IsBlank() {
// Treat blank fields as the zero value as the Go language requires.
- n = typecheck.Temp(n.Type().Field(0).Type)
+ n = typecheck.TempAt(base.Pos, ir.CurFunc, n.Type().Field(0).Type)
appendWalkStmt(init, ir.NewAssignStmt(base.Pos, n, nil))
continue
}
}
func copyExpr(n ir.Node, t *types.Type, init *ir.Nodes) ir.Node {
- l := typecheck.Temp(t)
+ l := typecheck.TempAt(base.Pos, ir.CurFunc, t)
appendWalkStmt(init, ir.NewAssignStmt(base.Pos, l, n))
return l
}
// to prevent that calls from clobbering arguments already on the stack.
if mayCall(arg) {
// assignment of arg to Temp
- tmp := typecheck.Temp(param.Type)
+ tmp := typecheck.TempAt(base.Pos, ir.CurFunc, param.Type)
init.Append(convas(typecheck.Stmt(ir.NewAssignStmt(base.Pos, tmp, arg)).(*ir.AssignStmt), init))
// replace arg with temp
args[i] = tmp
}
o.free[key] = a[:len(a)-1]
} else {
- v = typecheck.Temp(t)
+ v = typecheck.TempAt(base.Pos, ir.CurFunc, t)
}
if clear {
o.append(ir.NewAssignStmt(base.Pos, v, nil))
// order.stmt arranged for a copy of the array/slice variable if needed.
ha := a
- hv1 := typecheck.Temp(types.Types[types.TINT])
- hn := typecheck.Temp(types.Types[types.TINT])
+ hv1 := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
+ hn := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
init = append(init, ir.NewAssignStmt(base.Pos, hv1, nil))
init = append(init, ir.NewAssignStmt(base.Pos, hn, ir.NewUnaryExpr(base.Pos, ir.OLEN, ha)))
ptr.SetBounded(true)
huVal := ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUNSAFEPTR], ptr)
huVal = ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUINTPTR], huVal)
- hu := typecheck.Temp(types.Types[types.TUINTPTR])
+ hu := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TUINTPTR])
init = append(init, ir.NewAssignStmt(base.Pos, hu, huVal))
// Convert hu to hp at the top of the loop (after the condition has been checked).
hpVal := ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUNSAFEPTR], hu)
hpVal.SetCheckPtr(true) // disable checkptr on this conversion
hpVal = ir.NewConvExpr(base.Pos, ir.OCONVNOP, elem.PtrTo(), hpVal)
- hp := typecheck.Temp(elem.PtrTo())
+ hp := typecheck.TempAt(base.Pos, ir.CurFunc, elem.PtrTo())
body = append(body, ir.NewAssignStmt(base.Pos, hp, hpVal))
// Assign variables on the LHS of the range statement. Use *hp to get the element.
// order.stmt arranged for a copy of the channel variable.
ha := a
- hv1 := typecheck.Temp(t.Elem())
+ hv1 := typecheck.TempAt(base.Pos, ir.CurFunc, t.Elem())
hv1.SetTypecheck(1)
if t.Elem().HasPointers() {
init = append(init, ir.NewAssignStmt(base.Pos, hv1, nil))
}
- hb := typecheck.Temp(types.Types[types.TBOOL])
+ hb := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TBOOL])
nfor.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, hb, ir.NewBool(base.Pos, false))
lhs := []ir.Node{hv1, hb}
// order.stmt arranged for a copy of the string variable.
ha := a
- hv1 := typecheck.Temp(types.Types[types.TINT])
- hv1t := typecheck.Temp(types.Types[types.TINT])
- hv2 := typecheck.Temp(types.RuneType)
+ hv1 := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
+ hv1t := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
+ hv2 := typecheck.TempAt(base.Pos, ir.CurFunc, types.RuneType)
// hv1 := 0
init = append(init, ir.NewAssignStmt(base.Pos, hv1, nil))
n.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), ir.NewInt(base.Pos, 0))
// hp = &a[0]
- hp := typecheck.Temp(types.Types[types.TUNSAFEPTR])
+ hp := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TUNSAFEPTR])
ix := ir.NewIndexExpr(base.Pos, a, ir.NewInt(base.Pos, 0))
ix.SetBounded(true)
n.Body.Append(ir.NewAssignStmt(base.Pos, hp, addr))
// hn = len(a) * sizeof(elem(a))
- hn := typecheck.Temp(types.Types[types.TUINTPTR])
+ hn := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TUINTPTR])
mul := typecheck.Conv(ir.NewBinaryExpr(base.Pos, ir.OMUL, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), ir.NewInt(base.Pos, elemsize)), types.Types[types.TUINTPTR])
n.Body.Append(ir.NewAssignStmt(base.Pos, hn, mul))
if ir.IsBlank(elem) {
elem = typecheck.NodNil()
}
- cond = typecheck.Temp(types.Types[types.TBOOL])
+ cond = typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TBOOL])
fn := chanfn("selectnbrecv", 2, ch.Type())
call := mkcall1(fn, fn.Type().Results(), r.PtrInit(), elem, ch)
as := ir.NewAssignListStmt(r.Pos(), ir.OAS2, []ir.Node{cond, n.Lhs[1]}, []ir.Node{call})
// generate sel-struct
base.Pos = sellineno
- selv := typecheck.Temp(types.NewArray(scasetype(), int64(ncas)))
+ selv := typecheck.TempAt(base.Pos, ir.CurFunc, types.NewArray(scasetype(), int64(ncas)))
init = append(init, typecheck.Stmt(ir.NewAssignStmt(base.Pos, selv, nil)))
// No initialization for order; runtime.selectgo is responsible for that.
- order := typecheck.Temp(types.NewArray(types.Types[types.TUINT16], 2*int64(ncas)))
+ order := typecheck.TempAt(base.Pos, ir.CurFunc, types.NewArray(types.Types[types.TUINT16], 2*int64(ncas)))
var pc0, pcs ir.Node
if base.Flag.Race {
- pcs = typecheck.Temp(types.NewArray(types.Types[types.TUINTPTR], int64(ncas)))
+ pcs = typecheck.TempAt(base.Pos, ir.CurFunc, types.NewArray(types.Types[types.TUINTPTR], int64(ncas)))
pc0 = typecheck.Expr(typecheck.NodAddr(ir.NewIndexExpr(base.Pos, pcs, ir.NewInt(base.Pos, 0))))
} else {
pc0 = typecheck.NodNil()
// run the select
base.Pos = sellineno
- chosen := typecheck.Temp(types.Types[types.TINT])
- recvOK := typecheck.Temp(types.Types[types.TBOOL])
+ chosen := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
+ recvOK := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TBOOL])
r := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil)
r.Lhs = []ir.Node{chosen, recvOK}
fn := typecheck.LookupRuntime("selectgo")
s.facename = walkExpr(s.facename, sw.PtrInit())
s.facename = copyExpr(s.facename, s.facename.Type(), &sw.Compiled)
- s.okname = typecheck.Temp(types.Types[types.TBOOL])
+ s.okname = typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TBOOL])
// Get interface descriptor word.
// For empty interfaces this will be the type.
// allocated temporary variable of the given type. Statements to
// zero-initialize tmp are appended to init.
func stackTempAddr(init *ir.Nodes, typ *types.Type) *ir.AddrExpr {
- return initStackTemp(init, typecheck.Temp(typ), nil)
+ return initStackTemp(init, typecheck.TempAt(base.Pos, ir.CurFunc, typ), nil)
}
// stackBufAddr returns the expression &tmp, where tmp is a newly
if elem.HasPointers() {
base.FatalfAt(base.Pos, "%v has pointers", elem)
}
- tmp := typecheck.Temp(types.NewArray(elem, len))
+ tmp := typecheck.TempAt(base.Pos, ir.CurFunc, types.NewArray(elem, len))
return typecheck.Expr(typecheck.NodAddr(tmp)).(*ir.AddrExpr)
}