Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / honnef.co / go / tools@v0.0.1-2020.1.5 / ir / irutil / util.go
1 package irutil
2
3 import (
4         "honnef.co/go/tools/ir"
5 )
6
7 func Reachable(from, to *ir.BasicBlock) bool {
8         if from == to {
9                 return true
10         }
11         if from.Dominates(to) {
12                 return true
13         }
14
15         found := false
16         Walk(from, func(b *ir.BasicBlock) bool {
17                 if b == to {
18                         found = true
19                         return false
20                 }
21                 return true
22         })
23         return found
24 }
25
26 func Walk(b *ir.BasicBlock, fn func(*ir.BasicBlock) bool) {
27         seen := map[*ir.BasicBlock]bool{}
28         wl := []*ir.BasicBlock{b}
29         for len(wl) > 0 {
30                 b := wl[len(wl)-1]
31                 wl = wl[:len(wl)-1]
32                 if seen[b] {
33                         continue
34                 }
35                 seen[b] = true
36                 if !fn(b) {
37                         continue
38                 }
39                 wl = append(wl, b.Succs...)
40         }
41 }
42
43 func Vararg(x *ir.Slice) ([]ir.Value, bool) {
44         var out []ir.Value
45         slice, ok := x.X.(*ir.Alloc)
46         if !ok {
47                 return nil, false
48         }
49         for _, ref := range *slice.Referrers() {
50                 if ref == x {
51                         continue
52                 }
53                 if ref.Block() != x.Block() {
54                         return nil, false
55                 }
56                 idx, ok := ref.(*ir.IndexAddr)
57                 if !ok {
58                         return nil, false
59                 }
60                 if len(*idx.Referrers()) != 1 {
61                         return nil, false
62                 }
63                 store, ok := (*idx.Referrers())[0].(*ir.Store)
64                 if !ok {
65                         return nil, false
66                 }
67                 out = append(out, store.Val)
68         }
69         return out, true
70 }