@@ -163,7 +163,7 @@ class ASTWalker {
163
163
164
164
// The 'Action' set of types, which do not take a payload.
165
165
struct ContinueWalkAction {};
166
- struct SkipChildrenIfWalkAction { bool Cond; };
166
+ struct SkipChildrenIfWalkAction { bool Cond; bool SkipPostWalk; };
167
167
struct StopIfWalkAction { bool Cond; };
168
168
struct StopWalkAction {};
169
169
@@ -216,13 +216,30 @@ class ASTWalker {
216
216
return {Continue (), std::move (node)};
217
217
}
218
218
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.
220
229
template <typename T>
221
230
static _Detail::SkipChildrenIfWalkResult<T>
222
231
SkipNode (T node) {
223
232
return SkipNodeIf (true , std::move (node));
224
233
}
225
234
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
+
226
243
// / If \p cond is true, this is equivalent to \c Action::SkipNode(node).
227
244
// / Otherwise, it is equivalent to \c Action::Continue(node).
228
245
template <typename T>
@@ -231,6 +248,14 @@ class ASTWalker {
231
248
return {SkipNodeIf (cond), std::move (node)};
232
249
}
233
250
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
+
234
259
// / If \p cond is true, this is equivalent to \c Action::Continue(node).
235
260
// / Otherwise, it is equivalent to \c Action::SkipNode(node).
236
261
template <typename T>
@@ -249,16 +274,35 @@ class ASTWalker {
249
274
// / Continue the current walk.
250
275
static _Detail::ContinueWalkAction Continue () { return {}; }
251
276
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.
253
285
static _Detail::SkipChildrenIfWalkAction SkipNode () {
254
286
return SkipNodeIf (true );
255
287
}
256
288
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
+
257
295
// / If \p cond is true, this is equivalent to \c Action::SkipNode().
258
296
// / Otherwise, it is equivalent to \c Action::Continue().
259
297
static _Detail::SkipChildrenIfWalkAction
260
298
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);
262
306
}
263
307
264
308
// / If \p cond is true, this is equivalent to \c Action::Continue().
@@ -281,14 +325,19 @@ class ASTWalker {
281
325
// / A pre-visitation action for AST nodes that do not support being replaced
282
326
// / while walking.
283
327
struct PreWalkAction {
284
- enum Kind { Stop, SkipNode, Continue };
328
+ enum Kind { Stop, SkipChildren, SkipNode, Continue };
285
329
Kind Action;
286
330
287
331
PreWalkAction (_Detail::ContinueWalkAction) : Action(Continue) {}
288
332
PreWalkAction (_Detail::StopWalkAction) : Action(Stop) {}
289
333
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
+ }
292
341
293
342
PreWalkAction (_Detail::StopIfWalkAction action)
294
343
: Action(action.Cond ? Stop : Continue) {}
0 commit comments