Skip to content

Commit 560ecc9

Browse files
authored
Merge pull request #4402 from diffblue/exprt-visit-lamba2
exprt::visit post-order traversal variant
2 parents 2b74401 + f30d9db commit 560ecc9

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

src/util/expr.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,50 @@ const source_locationt &exprt::find_source_location() const
243243
return static_cast<const source_locationt &>(get_nil_irep());
244244
}
245245

246+
template <typename T>
247+
void visit_post_template(std::function<void(T &)> visitor, T *_expr)
248+
{
249+
struct stack_entryt
250+
{
251+
T *e;
252+
bool operands_pushed;
253+
explicit stack_entryt(T *_e) : e(_e), operands_pushed(false)
254+
{
255+
}
256+
};
257+
258+
std::stack<stack_entryt> stack;
259+
260+
stack.emplace(_expr);
261+
262+
while(!stack.empty())
263+
{
264+
auto &top = stack.top();
265+
if(top.operands_pushed)
266+
{
267+
visitor(*top.e);
268+
stack.pop();
269+
}
270+
else
271+
{
272+
// do modification of 'top' before pushing in case 'top' isn't stable
273+
top.operands_pushed = true;
274+
for(auto &op : top.e->operands())
275+
stack.emplace(&op);
276+
}
277+
}
278+
}
279+
280+
void exprt::visit_post(std::function<void(exprt &)> visitor)
281+
{
282+
visit_post_template(visitor, this);
283+
}
284+
285+
void exprt::visit_post(std::function<void(const exprt &)> visitor) const
286+
{
287+
visit_post_template(visitor, this);
288+
}
289+
246290
template <typename T>
247291
static void visit_pre_template(std::function<void(T &)> visitor, T *_expr)
248292
{

src/util/expr.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,12 @@ class exprt:public irept
332332
void visit_pre(std::function<void(exprt &)>);
333333
void visit_pre(std::function<void(const exprt &)>) const;
334334

335+
/// These are post-order traversal visitors, i.e.,
336+
/// the visitor is executed on a node _after_ its children
337+
/// have been visited.
338+
void visit_post(std::function<void(exprt &)>);
339+
void visit_post(std::function<void(const exprt &)>) const;
340+
335341
depth_iteratort depth_begin();
336342
depth_iteratort depth_end();
337343
const_depth_iteratort depth_begin() const;

0 commit comments

Comments
 (0)