// unreachable - mapped to cases below by exporter
case ir.OINDEX:
- return ir.NodAt(r.pos(), op, r.expr(), r.expr())
+ return ir.NodAt(r.pos(), ir.OINDEX, r.expr(), r.expr())
case ir.OSLICE, ir.OSLICE3:
- n := ir.NodAt(r.pos(), op, r.expr(), nil)
+ n := ir.NewSliceExpr(r.pos(), op, r.expr())
low, high := r.exprsOrNil()
var max ir.Node
if n.Op().IsSlice3() {
return n
// unary expressions
- case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ODEREF, ir.ONOT, ir.ORECV:
- return ir.NodAt(r.pos(), op, r.expr(), nil)
+ case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV:
+ return ir.NewUnaryExpr(r.pos(), op, r.expr())
+
case ir.OADDR:
return nodAddrAt(r.pos(), r.expr())
+ case ir.ODEREF:
+ return ir.NewStarExpr(r.pos(), r.expr())
+
// binary expressions
- case ir.OADD, ir.OAND, ir.OANDAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
- ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.OOROR, ir.ORSH, ir.OSEND, ir.OSUB, ir.OXOR:
- return ir.NodAt(r.pos(), op, r.expr(), r.expr())
+ case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
+ ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR:
+ return ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr())
+
+ case ir.OANDAND, ir.OOROR:
+ return ir.NewLogicalExpr(r.pos(), op, r.expr(), r.expr())
+
+ case ir.OSEND:
+ return ir.NewSendStmt(r.pos(), r.expr(), r.expr())
case ir.OADDSTR:
pos := r.pos()
// unreachable - generated by compiler for trampolin routines (not exported)
case ir.OGO, ir.ODEFER:
- return ir.NodAt(r.pos(), op, r.expr(), nil)
+ return ir.NewGoDeferStmt(r.pos(), op, r.expr())
case ir.OIF:
n := ir.NodAt(r.pos(), ir.OIF, nil, nil)
n.PtrBody().Set(r.stmtList())
return n
- case ir.OSELECT, ir.OSWITCH:
- n := ir.NodAt(r.pos(), op, nil, nil)
+ case ir.OSELECT:
+ n := ir.NodAt(r.pos(), ir.OSELECT, nil, nil)
+ n.PtrInit().Set(r.stmtList())
+ left, _ := r.exprsOrNil()
+ n.SetLeft(left)
+ n.PtrList().Set(r.caseList(n))
+ return n
+
+ case ir.OSWITCH:
+ n := ir.NodAt(r.pos(), ir.OSWITCH, nil, nil)
n.PtrInit().Set(r.stmtList())
left, _ := r.exprsOrNil()
n.SetLeft(left)
// case OEMPTY:
// unreachable - not emitted by exporter
- case ir.OBREAK, ir.OCONTINUE, ir.OGOTO, ir.OLABEL:
- n := ir.NodAt(r.pos(), op, nil, nil)
+ case ir.OBREAK, ir.OCONTINUE, ir.OGOTO:
+ var sym *types.Sym
+ pos := r.pos()
if label := r.string(); label != "" {
- n.SetSym(lookup(label))
+ sym = lookup(label)
}
- return n
+ return ir.NewBranchStmt(pos, op, sym)
+
+ case ir.OLABEL:
+ return ir.NewLabelStmt(r.pos(), lookup(r.string()))
case ir.OEND:
return nil
if expr.Full {
op = ir.OSLICE3
}
- n := p.nod(expr, op, p.expr(expr.X), nil)
+ n := ir.NewSliceExpr(p.pos(expr), op, p.expr(expr.X))
var index [3]ir.Node
for i, x := range &expr.Index {
if x != nil {
}
x := p.expr(expr.X)
if expr.Y == nil {
- return p.nod(expr, p.unOp(expr.Op), x, nil)
+ pos, op := p.pos(expr), p.unOp(expr.Op)
+ switch op {
+ case ir.OADDR:
+ return nodAddrAt(pos, x)
+ case ir.ODEREF:
+ return ir.NewStarExpr(pos, x)
+ }
+ return ir.NewUnaryExpr(pos, op, x)
+ }
+
+ pos, op, y := p.pos(expr), p.binOp(expr.Op), p.expr(expr.Y)
+ switch op {
+ case ir.OANDAND, ir.OOROR:
+ return ir.NewLogicalExpr(pos, op, x, y)
}
- return p.nod(expr, p.binOp(expr.Op), x, p.expr(expr.Y))
+ return ir.NewBinaryExpr(pos, op, x, y)
case *syntax.CallExpr:
n := p.nod(expr, ir.OCALL, p.expr(expr.Fun), nil)
n.PtrList().Set(p.exprs(expr.ArgList))
default:
panic("unhandled BranchStmt")
}
- n := p.nod(stmt, op, nil, nil)
+ var sym *types.Sym
if stmt.Label != nil {
- n.SetSym(p.name(stmt.Label))
+ sym = p.name(stmt.Label)
}
- return n
+ return ir.NewBranchStmt(p.pos(stmt), op, sym)
case *syntax.CallStmt:
var op ir.Op
switch stmt.Tok {
default:
panic("unhandled CallStmt")
}
- return p.nod(stmt, op, p.expr(stmt.Call), nil)
+ return ir.NewGoDeferStmt(p.pos(stmt), op, p.expr(stmt.Call))
case *syntax.ReturnStmt:
var results []ir.Node
if stmt.Results != nil {
l2.SetIndexMapLValue(false)
}
l2 = o.copyExpr(l2)
- r := ir.NodAt(n.Pos(), n.SubOp(), l2, n.Right())
- r = typecheck(r, ctxExpr)
- r = o.expr(r, nil)
- n = ir.NodAt(n.Pos(), ir.OAS, l1, r)
- n = typecheck(n, ctxStmt)
+ r := o.expr(typecheck(ir.NewBinaryExpr(n.Pos(), n.SubOp(), l2, n.Right()), ctxExpr), nil)
+ n = typecheck(ir.NodAt(n.Pos(), ir.OAS, l1, r), ctxStmt)
}
o.mapAssign(n)
case ir.ORECV:
// convert <-c into OSELRECV(_, <-c)
- n = ir.NodAt(n.Pos(), ir.OSELRECV, ir.BlankNode, n)
+ n = ir.NodAt(n.Pos(), ir.OAS, ir.BlankNode, n)
+ n.SetOp(ir.OSELRECV)
n.SetTypecheck(1)
ncase.SetLeft(n)
// Lower x, _ = <-c to x = <-c.
if n.Op() == ir.OSELRECV2 && ir.IsBlank(n.List().Second()) {
- n = ir.NodAt(n.Pos(), ir.OSELRECV, n.List().First(), n.Rlist().First())
+ n = ir.NodAt(n.Pos(), ir.OAS, n.List().First(), n.Rlist().First())
+ n.SetOp(ir.OSELRECV)
n.SetTypecheck(1)
cas.SetLeft(n)
}
op = ir.OCONV
}
- r := ir.Nod(op, n, nil)
- r.SetType(t)
+ r := ir.NewConvExpr(base.Pos, op, t, n)
r.SetTypecheck(1)
r.SetImplicit(true)
return r
fn.PtrBody().Append(n)
}
- dot := adddot(nodSym(ir.OXDOT, nthis, method.Sym))
+ dot := adddot(ir.NewSelectorExpr(base.Pos, ir.OXDOT, nthis, method.Sym))
// generate call
// It's not possible to use a tail call when dynamic linking on ppc64le. The
dowidth(l.Type())
if r.Type().IsInterface() == l.Type().IsInterface() || l.Type().Width >= 1<<16 {
- l = ir.Nod(aop, l, nil)
- l.SetType(r.Type())
+ l = ir.NewConvExpr(base.Pos, aop, r.Type(), l)
l.SetTypecheck(1)
n.SetLeft(l)
}
dowidth(r.Type())
if r.Type().IsInterface() == l.Type().IsInterface() || r.Type().Width >= 1<<16 {
- r = ir.Nod(aop, r, nil)
- r.SetType(l.Type())
+ r = ir.NewConvExpr(base.Pos, aop, l.Type(), r)
r.SetTypecheck(1)
n.SetRight(r)
}
switch l.SubOp() {
default:
base.Fatalf("unknown builtin %v", l)
- return n
case ir.OAPPEND, ir.ODELETE, ir.OMAKE, ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
n.SetOp(l.SubOp())
n.SetLeft(nil)
n.SetTypecheck(0) // re-typechecking new op is OK, not a loop
+ return typecheck(n, top)
case ir.OCAP, ir.OCLOSE, ir.OIMAG, ir.OLEN, ir.OPANIC, ir.OREAL:
typecheckargs(n)
n.SetType(nil)
return n
}
- old := n
- n = ir.NodAt(n.Pos(), l.SubOp(), arg, nil)
- n = initExpr(old.Init().Slice(), n) // typecheckargs can add to old.Init
+ u := ir.NewUnaryExpr(n.Pos(), l.SubOp(), arg)
+ return typecheck(initExpr(n.Init().Slice(), u), top) // typecheckargs can add to old.Init
case ir.OCOMPLEX, ir.OCOPY:
typecheckargs(n)
n.SetType(nil)
return n
}
- old := n
- n = ir.NodAt(n.Pos(), l.SubOp(), arg1, arg2)
- n = initExpr(old.Init().Slice(), n) // typecheckargs can add to old.Init
+ b := ir.NewBinaryExpr(n.Pos(), l.SubOp(), arg1, arg2)
+ return typecheck(initExpr(n.Init().Slice(), b), top) // typecheckargs can add to old.Init
}
- return typecheck(n, top)
+ panic("unreachable")
}
n.SetLeft(defaultlit(n.Left(), nil))
if n.Op() == ir.OASOP {
// Rewrite x op= y into x = x op y.
n = ir.Nod(ir.OAS, n.Left(),
- typecheck(ir.Nod(n.SubOp(), n.Left(), n.Right()), ctxExpr))
+ typecheck(ir.NewBinaryExpr(base.Pos, n.SubOp(), n.Left(), n.Right()), ctxExpr))
}
if oaslit(n, init) {
if l.Type().IsEmptyInterface() {
tab.SetType(types.NewPtr(types.Types[types.TUINT8]))
tab.SetTypecheck(1)
- eqtype = ir.Nod(eq, tab, rtyp)
+ eqtype = ir.NewBinaryExpr(base.Pos, eq, tab, rtyp)
} else {
- nonnil := ir.Nod(brcom(eq), nodnil(), tab)
- match := ir.Nod(eq, itabType(tab), rtyp)
- eqtype = ir.Nod(andor, nonnil, match)
+ nonnil := ir.NewBinaryExpr(base.Pos, brcom(eq), nodnil(), tab)
+ match := ir.NewBinaryExpr(base.Pos, eq, itabType(tab), rtyp)
+ eqtype = ir.NewLogicalExpr(base.Pos, andor, nonnil, match)
}
// Check for data equal.
- eqdata := ir.Nod(eq, ifaceData(n.Pos(), l, r.Type()), r)
+ eqdata := ir.NewBinaryExpr(base.Pos, eq, ifaceData(n.Pos(), l, r.Type()), r)
// Put it all together.
- expr := ir.Nod(andor, eqtype, eqdata)
+ expr := ir.NewLogicalExpr(base.Pos, andor, eqtype, eqdata)
n = finishcompare(n, expr, init)
return n
}
}
var expr ir.Node
compare := func(el, er ir.Node) {
- a := ir.Nod(n.Op(), el, er)
+ a := ir.NewBinaryExpr(base.Pos, n.Op(), el, er)
if expr == nil {
expr = a
} else {
- expr = ir.Nod(andor, expr, a)
+ expr = ir.NewLogicalExpr(base.Pos, andor, expr, a)
}
}
cmpl = safeexpr(cmpl, init)
if len(s) > 0 {
ncs = safeexpr(ncs, init)
}
- r := ir.Nod(cmp, ir.Nod(ir.OLEN, ncs, nil), nodintconst(int64(len(s))))
+ r := ir.Node(ir.NewBinaryExpr(base.Pos, cmp, ir.Nod(ir.OLEN, ncs, nil), nodintconst(int64(len(s)))))
remains := len(s)
for i := 0; remains > 0; {
if remains == 1 || !canCombineLoads {
cb := nodintconst(int64(s[i]))
ncb := ir.Nod(ir.OINDEX, ncs, nodintconst(int64(i)))
- r = ir.Nod(and, r, ir.Nod(cmp, ncb, cb))
+ r = ir.NewLogicalExpr(base.Pos, and, r, ir.NewBinaryExpr(base.Pos, cmp, ncb, cb))
remains--
i++
continue
}
csubstrPart := nodintconst(csubstr)
// Compare "step" bytes as once
- r = ir.Nod(and, r, ir.Nod(cmp, csubstrPart, ncsubstr))
+ r = ir.NewLogicalExpr(base.Pos, and, r, ir.NewBinaryExpr(base.Pos, cmp, csubstrPart, ncsubstr))
remains -= step
i += step
}
} else {
// sys_cmpstring(s1, s2) :: 0
r = mkcall("cmpstring", types.Types[types.TINT], init, conv(n.Left(), types.Types[types.TSTRING]), conv(n.Right(), types.Types[types.TSTRING]))
- r = ir.Nod(n.Op(), r, nodintconst(0))
+ r = ir.NewBinaryExpr(base.Pos, n.Op(), r, nodintconst(0))
}
return finishcompare(n, r, init)
if origArg == nil {
continue
}
- arg := ir.Nod(origArg.Op(), args[i], nil)
- arg.SetType(origArg.Type())
- args[i] = arg
+ args[i] = ir.NewConvExpr(base.Pos, origArg.Op(), origArg.Type(), args[i])
}
- call := ir.Nod(n.Op(), nil, nil)
+ call := ir.NewCallExpr(base.Pos, n.Op(), n.Left(), args)
if !isBuiltinCall {
call.SetOp(ir.OCALL)
- call.SetLeft(n.Left())
call.SetIsDDD(n.IsDDD())
}
- call.PtrList().Set(args)
fn.PtrBody().Set1(call)
funcbody()
typecheckslice(fn.Body().Slice(), ctxStmt)
xtop = append(xtop, fn)
- call = ir.Nod(ir.OCALL, nil, nil)
- call.SetLeft(fn.Nname)
- call.PtrList().Set(n.List().Slice())
- call = typecheck(call, ctxStmt)
- call = walkexpr(call, init)
- return call
+ call = ir.NewCallExpr(base.Pos, ir.OCALL, fn.Nname, n.List().Slice())
+ return walkexpr(typecheck(call, ctxStmt), init)
}
// substArgTypes substitutes the given list of types for