diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2022-01-04 15:28:37 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2022-01-11 16:30:08 +0100 |
| commit | d8ad35efe20c008e71b2359a09aee0662ede5eb9 (patch) | |
| tree | 57b89e80723261a1f5eea67ac6f5923a5be8acfb | |
| parent | 983508d80442a85b78118e6c6a03d5ae4897e4df (diff) | |
prog: support prunning recursion in ForeachType
| -rw-r--r-- | prog/types.go | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/prog/types.go b/prog/types.go index 110ddabeb..cca6f1d6c 100644 --- a/prog/types.go +++ b/prog/types.go @@ -676,6 +676,7 @@ type TypeCtx struct { Meta *Syscall Dir Dir Ptr *Type + Stop bool // If set by the callback, subtypes of this type are not visited. } func ForeachType(syscalls []*Syscall, f func(t Type, ctx *TypeCtx)) { @@ -701,8 +702,12 @@ func foreachTypeImpl(meta *Syscall, preorder bool, f func(t Type, ctx *TypeCtx)) seen := make(map[Type]bool) var rec func(*Type, Dir) rec = func(ptr *Type, dir Dir) { + ctx := &TypeCtx{Meta: meta, Dir: dir, Ptr: ptr} if preorder { - f(*ptr, &TypeCtx{Meta: meta, Dir: dir, Ptr: ptr}) + f(*ptr, ctx) + if ctx.Stop { + return + } } switch a := (*ptr).(type) { case *PtrType: @@ -733,7 +738,10 @@ func foreachTypeImpl(meta *Syscall, preorder bool, f func(t Type, ctx *TypeCtx)) panic("unknown type") } if !preorder { - f(*ptr, &TypeCtx{Meta: meta, Dir: dir, Ptr: ptr}) + f(*ptr, ctx) + if ctx.Stop { + panic("Stop is set in post-order iteration") + } } } for i := range meta.Args { |
