switch n.Op {
case OLABEL:
- if n.Left == nil || n.Left.Sym == nil {
+ if n.Sym == nil {
Fatalf("esc:label without label: %+v", n)
}
// Walk will complain about this label being already defined, but that's not until
// after escape analysis. in the future, maybe pull label & goto analysis out of walk and put before esc
- n.Left.Sym.Label = asTypesNode(&nonlooping)
+ n.Sym.Label = asTypesNode(&nonlooping)
case OGOTO:
- if n.Left == nil || n.Left.Sym == nil {
+ if n.Sym == nil {
Fatalf("esc:goto without label: %+v", n)
}
// If we come past one that's uninitialized, this must be a (harmless) forward jump
// but if it's set to nonlooping the label must have preceded this goto.
- if asNode(n.Left.Sym.Label) == &nonlooping {
- n.Left.Sym.Label = asTypesNode(&looping)
+ if asNode(n.Sym.Label) == &nonlooping {
+ n.Sym.Label = asTypesNode(&looping)
}
}
}
case OLABEL:
- if asNode(n.Left.Sym.Label) == &nonlooping {
+ switch asNode(n.Sym.Label) {
+ case &nonlooping:
if Debug['m'] > 2 {
fmt.Printf("%v:%v non-looping label\n", linestr(lineno), n)
}
- } else if asNode(n.Left.Sym.Label) == &looping {
+ case &looping:
if Debug['m'] > 2 {
fmt.Printf("%v: %v looping label\n", linestr(lineno), n)
}
e.loopdepth++
}
- n.Left.Sym.Label = nil
+ n.Sym.Label = nil
case ORANGE:
if n.List.Len() >= 2 {
mode.Fprintf(s, ": %v", n.Nbody)
case OBREAK, OCONTINUE, OGOTO, OFALL:
- if n.Left != nil {
- mode.Fprintf(s, "%#v %v", n.Op, n.Left)
+ if n.Sym != nil {
+ mode.Fprintf(s, "%#v %v", n.Op, n.Sym)
} else {
mode.Fprintf(s, "%#v", n.Op)
}
break
case OLABEL:
- mode.Fprintf(s, "%v: ", n.Left)
+ mode.Fprintf(s, "%v: ", n.Sym)
}
if extrablock {
case OGOTO, OLABEL:
w.op(op)
w.pos(n.Pos)
- w.expr(n.Left)
+ w.op(ONAME) // TODO(mdempsky): Remove toolstash hack.
+ w.string(n.Sym.Name)
default:
Fatalf("exporter: CANNOT EXPORT: %v\nPlease notify gri@\n", n.Op)
// unreachable - not emitted by exporter
case OGOTO, OLABEL:
- return nodl(r.pos(), op, newname(r.expr().Sym), nil)
+ n := nodl(r.pos(), op, nil, nil)
+ if op := r.op(); op != ONAME { // TODO(mdempsky): Remove toolstash check.
+ Fatalf("got %v, want ONAME", op)
+ }
+ n.Sym = lookup(r.string())
+ return n
case OEND:
return nil
body := subst.list(asNodes(fn.Func.Inl.Body))
- lab := nod(OLABEL, retlabel, nil)
+ lab := nodSym(OLABEL, nil, retlabel)
body = append(body, lab)
typecheckslice(body, Etop)
// function call.
type inlsubst struct {
// Target of the goto substituted in place of a return.
- retlabel *Node
+ retlabel *types.Sym
// Temporary result variables.
retvars []*Node
// dump("Return before substitution", n);
case ORETURN:
- m := nod(OGOTO, subst.retlabel, nil)
+ m := nodSym(OGOTO, nil, subst.retlabel)
m.Ninit.Set(subst.list(n.Ninit))
if len(subst.retvars) != 0 && n.List.Len() != 0 {
m := n.copy()
m.Pos = subst.updatedPos(m.Pos)
m.Ninit.Set(nil)
- p := fmt.Sprintf("%s·%d", n.Left.Sym.Name, inlgen)
- m.Left = newname(lookup(p))
+ p := fmt.Sprintf("%s·%d", n.Sym.Name, inlgen)
+ m.Sym = lookup(p)
return m
}
}
n := p.nod(stmt, op, nil, nil)
if stmt.Label != nil {
- n.Left = p.newname(stmt.Label)
+ n.Sym = p.name(stmt.Label)
}
return n
case *syntax.CallStmt:
}
func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) *Node {
- lhs := p.nod(label, OLABEL, p.newname(label.Label), nil)
+ lhs := p.nodSym(label, OLABEL, nil, p.name(label.Label))
var ls *Node
if label.Stmt != nil { // TODO(mdempsky): Should always be present.
}
case OLABEL:
- sym := n.Left.Sym
+ sym := n.Sym
lab := s.label(sym)
// Associate label with its control flow node, if any
s.startBlock(lab.target)
case OGOTO:
- sym := n.Left.Sym
+ sym := n.Sym
lab := s.label(sym)
if lab.target == nil {
case OCONTINUE, OBREAK:
var to *ssa.Block
- if n.Left == nil {
+ if n.Sym == nil {
// plain break/continue
switch n.Op {
case OCONTINUE:
}
} else {
// labeled break/continue; look up the target
- sym := n.Left.Sym
+ sym := n.Sym
lab := s.label(sym)
switch n.Op {
case OCONTINUE:
// to help with debugging.
// It should begin with "." to avoid conflicts with
// user labels.
-func autolabel(prefix string) *Node {
+func autolabel(prefix string) *types.Sym {
if prefix[0] != '.' {
Fatalf("autolabel prefix must start with '.', have %q", prefix)
}
}
n := fn.Func.Label
fn.Func.Label++
- return newname(lookupN(prefix, int(n)))
+ return lookupN(prefix, int(n))
}
func restrictlookup(name string, pkg *types.Pkg) *types.Sym {
n.Op = OCASE
needvar := n.List.Len() != 1 || n.List.First().Op == OLITERAL
- jmp := nod(OGOTO, autolabel(".s"), nil)
+ lbl := autolabel(".s")
+ jmp := nodSym(OGOTO, nil, lbl)
switch n.List.Len() {
case 0:
// default
}
}
- stat = append(stat, nod(OLABEL, jmp.Left, nil))
+ stat = append(stat, nodSym(OLABEL, nil, lbl))
if typeswvar != nil && needvar && n.Rlist.Len() != 0 {
l := []*Node{
nod(ODCL, n.Rlist.First(), nil),
} else {
// Jump to default case.
lbl := autolabel(".s")
- i.Nbody.Set1(nod(OGOTO, lbl, nil))
+ i.Nbody.Set1(nodSym(OGOTO, nil, lbl))
// Wrap default case with label.
blk := nod(OBLOCK, nil, nil)
- blk.List.Set2(nod(OLABEL, lbl, nil), def)
+ blk.List.Set2(nodSym(OLABEL, nil, lbl), def)
def = blk
}
i.Left = typecheck(i.Left, Erv)
// statements
OBLOCK // { List } (block of code)
- OBREAK // break
+ OBREAK // break [Sym]
OCASE // case Left or List[0]..List[1]: Nbody (select case after processing; Left==nil and List==nil means default)
OXCASE // case List: Nbody (select case before processing; List==nil means default)
- OCONTINUE // continue
+ OCONTINUE // continue [Sym]
ODEFER // defer Left (Left must be call)
OEMPTY // no-op (empty statement)
OFALL // fallthrough
// }
// OFORUNTIL is created by walk. There's no way to write this in Go code.
OFORUNTIL
- OGOTO // goto Left
+ OGOTO // goto Sym
OIF // if Ninit; Left { Nbody } else { Rlist }
- OLABEL // Left:
+ OLABEL // Sym:
OPROC // go Left (Left must be call)
ORANGE // for List = range Right { Nbody }
ORETURN // return List
case OLABEL:
ok |= Etop
decldepth++
- if n.Left.Sym.IsBlank() {
+ if n.Sym.IsBlank() {
// Empty identifier is valid but useless.
// Eliminate now to simplify life later.
// See issues 7538, 11589, 11593.
switch n.Op {
case OBREAK:
- if n.Left == nil {
+ if n.Sym == nil {
if implicit != nil {
implicit.SetHasBreak(true)
}
} else {
- lab := asNode(n.Left.Sym.Label)
+ lab := asNode(n.Sym.Label)
if lab != nil {
lab.SetHasBreak(true)
}
if n.Op == OLABEL && i+1 < len(s) && n.Name.Defn == s[i+1] {
switch n.Name.Defn.Op {
case OFOR, OFORUNTIL, OSWITCH, OTYPESW, OSELECT, ORANGE:
- n.Left.Sym.Label = asTypesNode(n.Name.Defn)
+ n.Sym.Label = asTypesNode(n.Name.Defn)
markbreak(n.Name.Defn, n.Name.Defn)
- n.Left.Sym.Label = nil
+ n.Sym.Label = nil
i++
continue
}