@@ -163,7 +163,7 @@ class ASTWalker {
163163
164164 // The 'Action' set of types, which do not take a payload.
165165 struct ContinueWalkAction {};
166- struct SkipChildrenIfWalkAction { bool Cond; };
166+ struct SkipChildrenIfWalkAction { bool Cond; bool SkipPostWalk; };
167167 struct StopIfWalkAction { bool Cond; };
168168 struct StopWalkAction {};
169169
@@ -216,13 +216,30 @@ class ASTWalker {
216216 return {Continue (), std::move (node)};
217217 }
218218
219- // / Skips visiting both the node's children and its post-visitation.
219+ // / Continue the current walk, replacing the current node with \p node.
220+ // / However, skip visiting the children of \p node, and resume at its
221+ // / post-walk.
222+ template <typename T>
223+ static _Detail::SkipChildrenIfWalkResult<T> SkipChildren (T node) {
224+ return SkipChildrenIf (true , std::move (node));
225+ }
226+
227+ // / Similar to \c Action::SkipChildren, but also skips the call to the
228+ // / post-visitation method.
220229 template <typename T>
221230 static _Detail::SkipChildrenIfWalkResult<T>
222231 SkipNode (T node) {
223232 return SkipNodeIf (true , std::move (node));
224233 }
225234
235+ // / If \p cond is true, this is equivalent to \c Action::SkipChildren(node).
236+ // / Otherwise, it is equivalent to \c Action::Continue(node).
237+ template <typename T>
238+ static _Detail::SkipChildrenIfWalkResult<T>
239+ SkipChildrenIf (bool cond, T node) {
240+ return {SkipChildrenIf (cond), std::move (node)};
241+ }
242+
226243 // / If \p cond is true, this is equivalent to \c Action::SkipNode(node).
227244 // / Otherwise, it is equivalent to \c Action::Continue(node).
228245 template <typename T>
@@ -231,6 +248,14 @@ class ASTWalker {
231248 return {SkipNodeIf (cond), std::move (node)};
232249 }
233250
251+ // / If \p cond is true, this is equivalent to \c Action::Continue(node).
252+ // / Otherwise, it is equivalent to \c Action::SkipChildren(node).
253+ template <typename T>
254+ static _Detail::SkipChildrenIfWalkResult<T>
255+ VisitChildrenIf (bool cond, T node) {
256+ return SkipChildrenIf (!cond, std::move (node));
257+ }
258+
234259 // / If \p cond is true, this is equivalent to \c Action::Continue(node).
235260 // / Otherwise, it is equivalent to \c Action::SkipNode(node).
236261 template <typename T>
@@ -249,16 +274,35 @@ class ASTWalker {
249274 // / Continue the current walk.
250275 static _Detail::ContinueWalkAction Continue () { return {}; }
251276
252- // / Skips visiting both the node's children and its post-visitation.
277+ // / Continue the current walk, but do not visit the children of the current
278+ // / node, resuming at its post-walk.
279+ static _Detail::SkipChildrenIfWalkAction SkipChildren () {
280+ return SkipChildrenIf (true );
281+ }
282+
283+ // / Similar to \c Action::SkipChildren, but also skips the call to the
284+ // / post-visitation method.
253285 static _Detail::SkipChildrenIfWalkAction SkipNode () {
254286 return SkipNodeIf (true );
255287 }
256288
289+ // / If \p cond is true, this is equivalent to \c Action::SkipChildren().
290+ // / Otherwise, it is equivalent to \c Action::Continue().
291+ static _Detail::SkipChildrenIfWalkAction SkipChildrenIf (bool cond) {
292+ return {cond, /* SkipPostWalk*/ false };
293+ }
294+
257295 // / If \p cond is true, this is equivalent to \c Action::SkipNode().
258296 // / Otherwise, it is equivalent to \c Action::Continue().
259297 static _Detail::SkipChildrenIfWalkAction
260298 SkipNodeIf (bool cond) {
261- return {cond};
299+ return {cond, /* SkipPostWalk*/ true };
300+ }
301+
302+ // / If \p cond is true, this is equivalent to \c Action::Continue().
303+ // / Otherwise, it is equivalent to \c Action::SkipChildren().
304+ static _Detail::SkipChildrenIfWalkAction VisitChildrenIf (bool cond) {
305+ return SkipChildrenIf (!cond);
262306 }
263307
264308 // / If \p cond is true, this is equivalent to \c Action::Continue().
@@ -281,14 +325,19 @@ class ASTWalker {
281325 // / A pre-visitation action for AST nodes that do not support being replaced
282326 // / while walking.
283327 struct PreWalkAction {
284- enum Kind { Stop, SkipNode, Continue };
328+ enum Kind { Stop, SkipChildren, SkipNode, Continue };
285329 Kind Action;
286330
287331 PreWalkAction (_Detail::ContinueWalkAction) : Action(Continue) {}
288332 PreWalkAction (_Detail::StopWalkAction) : Action(Stop) {}
289333
290- PreWalkAction (_Detail::SkipChildrenIfWalkAction action)
291- : Action(action.Cond ? SkipNode : Continue) {}
334+ PreWalkAction (_Detail::SkipChildrenIfWalkAction action) {
335+ if (action.Cond ) {
336+ Action = action.SkipPostWalk ? SkipNode : SkipChildren;
337+ } else {
338+ Action = Continue;
339+ }
340+ }
292341
293342 PreWalkAction (_Detail::StopIfWalkAction action)
294343 : Action(action.Cond ? Stop : Continue) {}
0 commit comments