@@ -163,23 +163,24 @@ 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
170
170
// The 'Result' set of types, which do take a payload.
171
171
template <typename T>
172
172
struct ContinueWalkResult {
173
+ ContinueWalkAction Action;
173
174
T Value;
174
175
};
175
176
template <typename T>
176
177
struct SkipChildrenIfWalkResult {
177
- bool Cond ;
178
+ SkipChildrenIfWalkAction Action ;
178
179
T Value;
179
180
};
180
181
template <typename T>
181
182
struct StopIfWalkResult {
182
- bool Cond ;
183
+ StopIfWalkAction Action ;
183
184
T Value;
184
185
};
185
186
};
@@ -212,23 +213,39 @@ class ASTWalker {
212
213
// / Continue the current walk, replacing the current node with \p node.
213
214
template <typename T>
214
215
static _Detail::ContinueWalkResult<T> Continue (T node) {
215
- return {std::move (node)};
216
+ return {Continue (), std::move (node)};
216
217
}
217
218
218
219
// / 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.
221
222
template <typename T>
222
223
static _Detail::SkipChildrenIfWalkResult<T> SkipChildren (T node) {
223
224
return SkipChildrenIf (true , std::move (node));
224
225
}
225
226
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
+
226
235
// / If \p cond is true, this is equivalent to \c Action::SkipChildren(node).
227
236
// / Otherwise, it is equivalent to \c Action::Continue(node).
228
237
template <typename T>
229
238
static _Detail::SkipChildrenIfWalkResult<T>
230
239
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)};
232
249
}
233
250
234
251
// / If \p cond is true, this is equivalent to \c Action::Continue(node).
@@ -239,26 +256,47 @@ class ASTWalker {
239
256
return SkipChildrenIf (!cond, std::move (node));
240
257
}
241
258
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
+
242
267
// / If \p cond is true, this is equivalent to \c Action::Stop().
243
268
// / Otherwise, it is equivalent to \c Action::Continue(node).
244
269
template <typename T>
245
270
static _Detail::StopIfWalkResult<T> StopIf (bool cond, T node) {
246
- return {cond, std::move (node)};
271
+ return {StopIf ( cond) , std::move (node)};
247
272
}
248
273
249
274
// / Continue the current walk.
250
275
static _Detail::ContinueWalkAction Continue () { return {}; }
251
276
252
277
// / 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.
254
279
static _Detail::SkipChildrenIfWalkAction SkipChildren () {
255
280
return SkipChildrenIf (true );
256
281
}
257
282
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
+
258
289
// / If \p cond is true, this is equivalent to \c Action::SkipChildren().
259
290
// / Otherwise, it is equivalent to \c Action::Continue().
260
291
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 };
262
300
}
263
301
264
302
// / If \p cond is true, this is equivalent to \c Action::Continue().
@@ -267,6 +305,13 @@ class ASTWalker {
267
305
return SkipChildrenIf (!cond);
268
306
}
269
307
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
+
270
315
// / Terminate the walk, returning without visiting any other nodes.
271
316
static _Detail::StopWalkAction Stop () { return {}; }
272
317
@@ -280,16 +325,19 @@ class ASTWalker {
280
325
// / A pre-visitation action for AST nodes that do not support being replaced
281
326
// / while walking.
282
327
struct PreWalkAction {
283
- enum Kind { Stop, SkipChildren, Continue };
328
+ enum Kind { Stop, SkipChildren, SkipNode, Continue };
284
329
Kind Action;
285
330
286
- PreWalkAction (Kind action) : Action(action) {}
287
-
288
331
PreWalkAction (_Detail::ContinueWalkAction) : Action(Continue) {}
289
332
PreWalkAction (_Detail::StopWalkAction) : Action(Stop) {}
290
333
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
+ }
293
341
294
342
PreWalkAction (_Detail::StopIfWalkAction action)
295
343
: Action(action.Cond ? Stop : Continue) {}
@@ -303,8 +351,6 @@ class ASTWalker {
303
351
enum Kind { Stop, Continue };
304
352
Kind Action;
305
353
306
- PostWalkAction (Kind action) : Action(action) {}
307
-
308
354
PostWalkAction (_Detail::ContinueWalkAction) : Action(Continue) {}
309
355
PostWalkAction (_Detail::StopWalkAction) : Action(Stop) {}
310
356
@@ -340,21 +386,18 @@ class ASTWalker {
340
386
341
387
template <typename U>
342
388
PreWalkResult (_Detail::ContinueWalkResult<U> Result)
343
- : Action(PreWalkAction::Continue ), Value(std::move(Result.Value)) {}
389
+ : Action(Result.Action ), Value(std::move(Result.Value)) {}
344
390
345
391
template <typename U>
346
392
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)) {}
350
394
351
395
template <typename U>
352
396
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)) {}
355
398
356
- PreWalkResult (_Detail::StopWalkAction)
357
- : Action(PreWalkAction::Stop ), Value(llvm::None) {}
399
+ PreWalkResult (_Detail::StopWalkAction Action )
400
+ : Action(Action ), Value(llvm::None) {}
358
401
};
359
402
360
403
// / Do not construct directly, use \c Action::<action> instead.
@@ -385,15 +428,14 @@ class ASTWalker {
385
428
386
429
template <typename U>
387
430
PostWalkResult (_Detail::ContinueWalkResult<U> Result)
388
- : Action(PostWalkAction::Continue ), Value(std::move(Result.Value)) {}
431
+ : Action(Result.Action ), Value(std::move(Result.Value)) {}
389
432
390
433
template <typename U>
391
434
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)) {}
394
436
395
- PostWalkResult (_Detail::StopWalkAction)
396
- : Action(PostWalkAction::Stop ), Value(llvm::None) {}
437
+ PostWalkResult (_Detail::StopWalkAction Action )
438
+ : Action(Action ), Value(llvm::None) {}
397
439
};
398
440
399
441
// / This method is called when first visiting an expression
0 commit comments