@@ -163,23 +163,24 @@ 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
170170 // The 'Result' set of types, which do take a payload.
171171 template <typename T>
172172 struct ContinueWalkResult {
173+ ContinueWalkAction Action;
173174 T Value;
174175 };
175176 template <typename T>
176177 struct SkipChildrenIfWalkResult {
177- bool Cond ;
178+ SkipChildrenIfWalkAction Action ;
178179 T Value;
179180 };
180181 template <typename T>
181182 struct StopIfWalkResult {
182- bool Cond ;
183+ StopIfWalkAction Action ;
183184 T Value;
184185 };
185186 };
@@ -212,23 +213,39 @@ class ASTWalker {
212213 // / Continue the current walk, replacing the current node with \p node.
213214 template <typename T>
214215 static _Detail::ContinueWalkResult<T> Continue (T node) {
215- return {std::move (node)};
216+ return {Continue (), std::move (node)};
216217 }
217218
218219 // / Continue the current walk, replacing the current node with \p node.
219- // / However, skip visiting the children of \p node, and instead resume the
220- // / walk of the parent node .
220+ // / However, skip visiting the children of \p node, and resume at its
221+ // / post- walk.
221222 template <typename T>
222223 static _Detail::SkipChildrenIfWalkResult<T> SkipChildren (T node) {
223224 return SkipChildrenIf (true , std::move (node));
224225 }
225226
227+ // / Similar to \c Action::SkipChildren, but also skips the call to the
228+ // / post-visitation method.
229+ template <typename T>
230+ static _Detail::SkipChildrenIfWalkResult<T>
231+ SkipNode (T node) {
232+ return SkipNodeIf (true , std::move (node));
233+ }
234+
226235 // / If \p cond is true, this is equivalent to \c Action::SkipChildren(node).
227236 // / Otherwise, it is equivalent to \c Action::Continue(node).
228237 template <typename T>
229238 static _Detail::SkipChildrenIfWalkResult<T>
230239 SkipChildrenIf (bool cond, T node) {
231- return {cond, std::move (node)};
240+ return {SkipChildrenIf (cond), std::move (node)};
241+ }
242+
243+ // / If \p cond is true, this is equivalent to \c Action::SkipNode(node).
244+ // / Otherwise, it is equivalent to \c Action::Continue(node).
245+ template <typename T>
246+ static _Detail::SkipChildrenIfWalkResult<T>
247+ SkipNodeIf (bool cond, T node) {
248+ return {SkipNodeIf (cond), std::move (node)};
232249 }
233250
234251 // / If \p cond is true, this is equivalent to \c Action::Continue(node).
@@ -239,26 +256,47 @@ class ASTWalker {
239256 return SkipChildrenIf (!cond, std::move (node));
240257 }
241258
259+ // / If \p cond is true, this is equivalent to \c Action::Continue(node).
260+ // / Otherwise, it is equivalent to \c Action::SkipNode(node).
261+ template <typename T>
262+ static _Detail::SkipChildrenIfWalkResult<T>
263+ VisitNodeIf (bool cond, T node) {
264+ return SkipNodeIf (!cond, std::move (node));
265+ }
266+
242267 // / If \p cond is true, this is equivalent to \c Action::Stop().
243268 // / Otherwise, it is equivalent to \c Action::Continue(node).
244269 template <typename T>
245270 static _Detail::StopIfWalkResult<T> StopIf (bool cond, T node) {
246- return {cond, std::move (node)};
271+ return {StopIf ( cond) , std::move (node)};
247272 }
248273
249274 // / Continue the current walk.
250275 static _Detail::ContinueWalkAction Continue () { return {}; }
251276
252277 // / Continue the current walk, but do not visit the children of the current
253- // / node. Instead, resume at the parent's post-walk.
278+ // / node, resuming at its post-walk.
254279 static _Detail::SkipChildrenIfWalkAction SkipChildren () {
255280 return SkipChildrenIf (true );
256281 }
257282
283+ // / Similar to \c Action::SkipChildren, but also skips the call to the
284+ // / post-visitation method.
285+ static _Detail::SkipChildrenIfWalkAction SkipNode () {
286+ return SkipNodeIf (true );
287+ }
288+
258289 // / If \p cond is true, this is equivalent to \c Action::SkipChildren().
259290 // / Otherwise, it is equivalent to \c Action::Continue().
260291 static _Detail::SkipChildrenIfWalkAction SkipChildrenIf (bool cond) {
261- return {cond};
292+ return {cond, /* SkipPostWalk*/ false };
293+ }
294+
295+ // / If \p cond is true, this is equivalent to \c Action::SkipNode().
296+ // / Otherwise, it is equivalent to \c Action::Continue().
297+ static _Detail::SkipChildrenIfWalkAction
298+ SkipNodeIf (bool cond) {
299+ return {cond, /* SkipPostWalk*/ true };
262300 }
263301
264302 // / If \p cond is true, this is equivalent to \c Action::Continue().
@@ -267,6 +305,13 @@ class ASTWalker {
267305 return SkipChildrenIf (!cond);
268306 }
269307
308+ // / If \p cond is true, this is equivalent to \c Action::Continue().
309+ // / Otherwise, it is equivalent to \c Action::SkipNode().
310+ static _Detail::SkipChildrenIfWalkAction
311+ VisitNodeIf (bool cond) {
312+ return SkipNodeIf (!cond);
313+ }
314+
270315 // / Terminate the walk, returning without visiting any other nodes.
271316 static _Detail::StopWalkAction Stop () { return {}; }
272317
@@ -280,16 +325,19 @@ class ASTWalker {
280325 // / A pre-visitation action for AST nodes that do not support being replaced
281326 // / while walking.
282327 struct PreWalkAction {
283- enum Kind { Stop, SkipChildren, Continue };
328+ enum Kind { Stop, SkipChildren, SkipNode, Continue };
284329 Kind Action;
285330
286- PreWalkAction (Kind action) : Action(action) {}
287-
288331 PreWalkAction (_Detail::ContinueWalkAction) : Action(Continue) {}
289332 PreWalkAction (_Detail::StopWalkAction) : Action(Stop) {}
290333
291- PreWalkAction (_Detail::SkipChildrenIfWalkAction action)
292- : Action(action.Cond ? SkipChildren : Continue) {}
334+ PreWalkAction (_Detail::SkipChildrenIfWalkAction action) {
335+ if (action.Cond ) {
336+ Action = action.SkipPostWalk ? SkipNode : SkipChildren;
337+ } else {
338+ Action = Continue;
339+ }
340+ }
293341
294342 PreWalkAction (_Detail::StopIfWalkAction action)
295343 : Action(action.Cond ? Stop : Continue) {}
@@ -303,8 +351,6 @@ class ASTWalker {
303351 enum Kind { Stop, Continue };
304352 Kind Action;
305353
306- PostWalkAction (Kind action) : Action(action) {}
307-
308354 PostWalkAction (_Detail::ContinueWalkAction) : Action(Continue) {}
309355 PostWalkAction (_Detail::StopWalkAction) : Action(Stop) {}
310356
@@ -340,21 +386,18 @@ class ASTWalker {
340386
341387 template <typename U>
342388 PreWalkResult (_Detail::ContinueWalkResult<U> Result)
343- : Action(PreWalkAction::Continue ), Value(std::move(Result.Value)) {}
389+ : Action(Result.Action ), Value(std::move(Result.Value)) {}
344390
345391 template <typename U>
346392 PreWalkResult (_Detail::SkipChildrenIfWalkResult<U> Result)
347- : Action(Result.Cond ? PreWalkAction::SkipChildren
348- : PreWalkAction::Continue),
349- Value (std::move(Result.Value)) {}
393+ : Action(Result.Action), Value(std::move(Result.Value)) {}
350394
351395 template <typename U>
352396 PreWalkResult (_Detail::StopIfWalkResult<U> Result)
353- : Action(Result.Cond ? PreWalkAction::Stop : PreWalkAction::Continue),
354- Value(std::move(Result.Value)) {}
397+ : Action(Result.Action), Value(std::move(Result.Value)) {}
355398
356- PreWalkResult (_Detail::StopWalkAction)
357- : Action(PreWalkAction::Stop ), Value(llvm::None) {}
399+ PreWalkResult (_Detail::StopWalkAction Action )
400+ : Action(Action ), Value(llvm::None) {}
358401 };
359402
360403 // / Do not construct directly, use \c Action::<action> instead.
@@ -385,15 +428,14 @@ class ASTWalker {
385428
386429 template <typename U>
387430 PostWalkResult (_Detail::ContinueWalkResult<U> Result)
388- : Action(PostWalkAction::Continue ), Value(std::move(Result.Value)) {}
431+ : Action(Result.Action ), Value(std::move(Result.Value)) {}
389432
390433 template <typename U>
391434 PostWalkResult (_Detail::StopIfWalkResult<U> Result)
392- : Action(Result.Cond ? PostWalkAction::Stop : PostWalkAction::Continue),
393- Value (std::move(Result.Value)) {}
435+ : Action(Result.Action), Value(std::move(Result.Value)) {}
394436
395- PostWalkResult (_Detail::StopWalkAction)
396- : Action(PostWalkAction::Stop ), Value(llvm::None) {}
437+ PostWalkResult (_Detail::StopWalkAction Action )
438+ : Action(Action ), Value(llvm::None) {}
397439 };
398440
399441 // / This method is called when first visiting an expression
0 commit comments