// Turn an OINLCALL into a statement.
func inlconv2stmt(inlcall ir.Node) ir.Node {
n := ir.NodAt(inlcall.Pos(), ir.OBLOCK, nil, nil)
- n.SetList(inlcall.Body())
- n.SetInit(inlcall.Init())
+ n.SetList(inlcall.Init())
+ n.PtrList().AppendNodes(inlcall.PtrBody())
return n
}
// Turn the rlist (with the return values) of the OINLCALL in
// n into an expression list lumping the ninit and body
// containing the inlined statements on the first list element so
-// order will be preserved Used in return, oas2func and call
+// order will be preserved. Used in return, oas2func and call
// statements.
func inlconv2list(n ir.Node) []ir.Node {
if n.Op() != ir.OINLCALL || n.Rlist().Len() == 0 {
// dump("Return before substitution", n);
case ir.ORETURN:
- m := nodSym(ir.OGOTO, nil, subst.retlabel)
- m.PtrInit().Set(subst.list(n.Init()))
-
+ init := subst.list(n.Init())
if len(subst.retvars) != 0 && n.List().Len() != 0 {
as := ir.Nod(ir.OAS2, nil, nil)
}
as = typecheck(as, ctxStmt)
- m.PtrInit().Append(as)
+ init = append(init, as)
}
-
- typecheckslice(m.Init().Slice(), ctxStmt)
- m = typecheck(m, ctxStmt)
-
- // dump("Return after substitution", m);
- return m
+ init = append(init, nodSym(ir.OGOTO, nil, subst.retlabel))
+ typecheckslice(init, ctxStmt)
+ return ir.NewBlockStmt(base.Pos, init)
case ir.OGOTO, ir.OLABEL:
m := ir.Copy(n)
if n.Typecheck() == 0 {
base.Fatalf("missing typecheck: %+v", n)
}
- wascopy := n.Op() == ir.OCOPY
init := n.Init()
n.PtrInit().Set(nil)
n = walkexpr(n, &init)
- if wascopy && n.Op() == ir.ONAME {
+ if n.Op() == ir.ONAME {
// copy rewrote to a statement list and a temp for the length.
// Throw away the temp to avoid plain values as statements.
- n = ir.NodAt(n.Pos(), ir.OBLOCK, nil, nil)
+ n = ir.NewBlockStmt(n.Pos(), init.Slice())
+ init.Set(nil)
+ }
+ if init.Len() > 0 {
+ switch n.Op() {
+ case ir.OAS, ir.OAS2, ir.OBLOCK:
+ n.PtrInit().Prepend(init.Slice()...)
+
+ default:
+ init.Append(n)
+ n = ir.NewBlockStmt(n.Pos(), init.Slice())
+ }
}
- n = addinit(n, init.Slice())
// special case for a receive where we throw away
// the value received.
}
fallthrough
case ir.OGO:
+ var init ir.Nodes
switch n.Left().Op() {
case ir.OPRINT, ir.OPRINTN:
- n.SetLeft(wrapCall(n.Left(), n.PtrInit()))
+ n.SetLeft(wrapCall(n.Left(), &init))
case ir.ODELETE:
if mapfast(n.Left().List().First().Type()) == mapslow {
- n.SetLeft(wrapCall(n.Left(), n.PtrInit()))
+ n.SetLeft(wrapCall(n.Left(), &init))
} else {
- n.SetLeft(walkexpr(n.Left(), n.PtrInit()))
+ n.SetLeft(walkexpr(n.Left(), &init))
}
case ir.OCOPY:
- n.SetLeft(copyany(n.Left(), n.PtrInit(), true))
+ n.SetLeft(copyany(n.Left(), &init, true))
case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
if n.Left().Body().Len() > 0 {
- n.SetLeft(wrapCall(n.Left(), n.PtrInit()))
+ n.SetLeft(wrapCall(n.Left(), &init))
} else {
- n.SetLeft(walkexpr(n.Left(), n.PtrInit()))
+ n.SetLeft(walkexpr(n.Left(), &init))
}
default:
- n.SetLeft(walkexpr(n.Left(), n.PtrInit()))
+ n.SetLeft(walkexpr(n.Left(), &init))
+ }
+ if init.Len() > 0 {
+ init.Append(n)
+ n = ir.NewBlockStmt(n.Pos(), init.Slice())
}
case ir.OFOR, ir.OFORUNTIL: