}
(*budget)--
- // TODO(mdempsky): Hack to appease toolstash; remove.
- if n.Op == OSTRUCTKEY {
+ // TODO(mdempsky/josharian): Hacks to appease toolstash; remove.
+ // See issue 17566 and CL 31674 for discussion.
+ switch n.Op {
+ case OSTRUCTKEY:
+ (*budget)--
+ case OSLICE, OSLICEARR, OSLICESTR:
(*budget)--
+ case OSLICE3, OSLICE3ARR:
+ *budget -= 2
}
return *budget < 0 || ishairy(n.Left, budget, reason) || ishairy(n.Right, budget, reason) ||
default:
s := n.List.Slice()
for i1, n1 := range s {
- if n1.Op == OINLCALL {
+ if n1 != nil && n1.Op == OINLCALL {
s[i1] = inlconv2expr(s[i1])
}
}
// SliceBounds returns n's slice bounds: low, high, and max in expr[low:high:max].
// n must be a slice expression. max is nil if n is a simple slice expression.
func (n *Node) SliceBounds() (low, high, max *Node) {
+ if n.List.Len() == 0 {
+ return nil, nil, nil
+ }
+
switch n.Op {
case OSLICE, OSLICEARR, OSLICESTR:
- if n.Right == nil {
- return nil, nil, nil
- }
- if n.Right.Op != OKEY {
- Fatalf("SliceBounds right %s", opnames[n.Right.Op])
- }
- return n.Right.Left, n.Right.Right, nil
+ s := n.List.Slice()
+ return s[0], s[1], nil
case OSLICE3, OSLICE3ARR:
- if n.Right.Op != OKEY || n.Right.Right.Op != OKEY {
- Fatalf("SliceBounds right %s %s", opnames[n.Right.Op], opnames[n.Right.Right.Op])
- }
- return n.Right.Left, n.Right.Right.Left, n.Right.Right.Right
+ s := n.List.Slice()
+ return s[0], s[1], s[2]
}
Fatalf("SliceBounds op %v: %v", n.Op, n)
return nil, nil, nil
if max != nil {
Fatalf("SetSliceBounds %v given three bounds", n.Op)
}
- if n.Right == nil {
- n.Right = nod(OKEY, low, high)
+ s := n.List.Slice()
+ if s == nil {
+ if low == nil && high == nil {
+ return
+ }
+ n.List.Set([]*Node{low, high})
return
}
- n.Right.Left = low
- n.Right.Right = high
+ s[0] = low
+ s[1] = high
return
case OSLICE3, OSLICE3ARR:
- if n.Right == nil {
- n.Right = nod(OKEY, low, nod(OKEY, high, max))
+ s := n.List.Slice()
+ if s == nil {
+ if low == nil && high == nil && max == nil {
+ return
+ }
+ n.List.Set([]*Node{low, high, max})
+ return
}
- n.Right.Left = low
- n.Right.Right.Left = high
- n.Right.Right.Right = max
+ s[0] = low
+ s[1] = high
+ s[2] = max
return
}
Fatalf("SetSliceBounds op %v: %v", n.Op, n)
OPRINTN // println(List)
OPAREN // (Left)
OSEND // Left <- Right
- OSLICE // Left[Right.Left : Right.Right] (Left is untypechecked or slice; Right.Op==OKEY)
- OSLICEARR // Left[Right.Left : Right.Right] (Left is array)
- OSLICESTR // Left[Right.Left : Right.Right] (Left is string)
- OSLICE3 // Left[R.Left : R.R.Left : R.R.R] (R=Right; Left is untypedchecked or slice; R.Op and R.R.Op==OKEY)
- OSLICE3ARR // Left[R.Left : R.R.Left : R.R.R] (R=Right; Left is array; R.Op and R.R.Op==OKEY)
+ OSLICE // Left[List[0] : List[1]] (Left is untypechecked or slice)
+ OSLICEARR // Left[List[0] : List[1]] (Left is array)
+ OSLICESTR // Left[List[0] : List[1]] (Left is string)
+ OSLICE3 // Left[List[0] : List[1] : List[2]] (Left is untypedchecked or slice)
+ OSLICE3ARR // Left[List[0] : List[1] : List[2]] (Left is array)
ORECOVER // recover()
ORECV // <-Left
ORUNESTR // Type(Left) (Type is string, Left is rune)