File tree Expand file tree Collapse file tree 4 files changed +63
-0
lines changed
Expand file tree Collapse file tree 4 files changed +63
-0
lines changed Original file line number Diff line number Diff line change @@ -279,6 +279,20 @@ void exprt::visit(const_expr_visitort &visitor) const
279279 }
280280}
281281
282+ void exprt::visit (const std::function<void (const exprt &)> &f) const
283+ {
284+ std::stack<const exprt *> stack;
285+ stack.push (this );
286+ while (!stack.empty ())
287+ {
288+ const exprt &expr = *stack.top ();
289+ stack.pop ();
290+ f (expr);
291+ forall_operands (it, expr)
292+ stack.push (&(*it));
293+ }
294+ }
295+
282296depth_iteratort exprt::depth_begin ()
283297{ return depth_iteratort (*this ); }
284298depth_iteratort exprt::depth_end ()
Original file line number Diff line number Diff line change @@ -305,6 +305,12 @@ class exprt:public irept
305305 void visit (class expr_visitort &visitor);
306306 void visit (class const_expr_visitort &visitor) const ;
307307
308+ // / Recursively traverse the expression tree (via operands) and call \p f on
309+ // / every subexpressions, including `this`. The input function has
310+ // / side-effects and does not modify the expression.
311+ // / \param f: The function to be call on subexpressions
312+ void visit (const std::function<void (const exprt &)> &f) const ;
313+
308314 depth_iteratort depth_begin ();
309315 depth_iteratort depth_end ();
310316 const_depth_iteratort depth_begin () const ;
Original file line number Diff line number Diff line change @@ -56,6 +56,7 @@ SRC += analyses/ai/ai.cpp \
5656 util/string_utils/strip_string.cpp \
5757 util/symbol_table.cpp \
5858 util/unicode.cpp \
59+ util/visit.cpp \
5960 # Empty last line
6061
6162INCLUDES = -I ../src/ -I.
Original file line number Diff line number Diff line change 1+ /* ******************************************************************\
2+
3+ Module: Unit test for expr.h/visit
4+
5+ Author: Diffblue Ltd
6+
7+ \*******************************************************************/
8+
9+ #include < testing-utils/catch.hpp>
10+
11+ #include < util/arith_tools.h>
12+ #include < util/expr.h>
13+ #include < util/std_expr.h>
14+ #include < util/std_types.h>
15+
16+ SCENARIO (" visiting reaches all subnodes" , " [core][util][expr]" )
17+ {
18+ GIVEN (" An exprt representing a binary relation" )
19+ {
20+ const typet type1 = signedbv_typet (32 );
21+ irep_idt symbol_name = " a" ;
22+ symbol_exprt varx (symbol_name, type1);
23+ exprt val10 = from_integer (10 , type1);
24+ binary_relation_exprt x_le_10 (varx, ID_le, val10);
25+
26+ THEN (" counting nodes should return 3" )
27+ {
28+ size_t count = 0 ;
29+ x_le_10.visit ([&](const exprt &) { count++; });
30+ REQUIRE (count == 3 );
31+ }
32+ THEN (" counting symbol should return 1" )
33+ {
34+ size_t count = 0 ;
35+ x_le_10.visit ([&](const exprt &e) {
36+ if (e.id () == ID_symbol)
37+ count++;
38+ });
39+ REQUIRE (count == 1 );
40+ }
41+ }
42+ }
You can’t perform that action at this time.
0 commit comments