// Don't do special substitutions if inside a closure
break
}
- // Since we don't handle bodies with closures,
+ // Because of the above test for subst.newclofn,
// this return is guaranteed to belong to the current inlined function.
n := n.(*ir.ReturnStmt)
init := subst.list(n.Init())
typecheck.Stmts(init)
return ir.NewBlockStmt(base.Pos, init)
- case ir.OGOTO:
+ case ir.OGOTO, ir.OBREAK, ir.OCONTINUE:
if subst.newclofn != nil {
// Don't do special substitutions if inside a closure
break
m := ir.Copy(n).(*ir.BranchStmt)
m.SetPos(subst.updatedPos(m.Pos()))
*m.PtrInit() = nil
- p := fmt.Sprintf("%s·%d", n.Label.Name, inlgen)
- m.Label = typecheck.Lookup(p)
+ m.Label = translateLabel(n.Label)
return m
case ir.OLABEL:
m := ir.Copy(n).(*ir.LabelStmt)
m.SetPos(subst.updatedPos(m.Pos()))
*m.PtrInit() = nil
- p := fmt.Sprintf("%s·%d", n.Label.Name, inlgen)
- m.Label = typecheck.Lookup(p)
+ m.Label = translateLabel(n.Label)
return m
case ir.OCLOSURE:
m.SetPos(subst.updatedPos(m.Pos()))
ir.EditChildren(m, subst.edit)
+ if subst.newclofn == nil {
+ // Translate any label on FOR or RANGE loops
+ if m.Op() == ir.OFOR {
+ m := m.(*ir.ForStmt)
+ m.Label = translateLabel(m.Label)
+ return m
+ }
+
+ if m.Op() == ir.ORANGE {
+ m := m.(*ir.RangeStmt)
+ m.Label = translateLabel(m.Label)
+ return m
+ }
+ }
+
switch m := m.(type) {
case *ir.AssignStmt:
if lhs, ok := m.X.(*ir.Name); ok && lhs.Defn == &subst.defnMarker {
return m
}
+// translateLabel makes a label from an inlined function (if non-nil) be unique by
+// adding "·inlgen".
+func translateLabel(l *types.Sym) *types.Sym {
+ if l == nil {
+ return nil
+ }
+ p := fmt.Sprintf("%s·%d", l.Name, inlgen)
+ return typecheck.Lookup(p)
+}
+
func (subst *inlsubst) updatedPos(xpos src.XPos) src.XPos {
if subst.noPosUpdate {
return xpos