@@ -187,10 +187,25 @@ visitFunctionDecl(ASTWalker &Walker, AbstractFunctionDecl *AFD, F Func) {
187
187
return ASTWalker::Action::SkipChildren ();
188
188
}
189
189
190
- // / Whether to skip visitation of an expression. Children of skipped exprs
191
- // / should still be visited.
192
- static bool skipExpr (Expr *E) {
193
- return !E->getStartLoc ().isValid () || !E->getEndLoc ().isValid ();
190
+ // / Whether to skip visitation of an expression. If the expression should be
191
+ // / skipped, a walker action is returned that determines whether or not the
192
+ // / children should also be skipped.
193
+ static Optional<ASTWalker::PreWalkResult<Expr *>>
194
+ shouldSkipExpr (Expr *E, ASTWalker::ParentTy Parent) {
195
+ using Action = ASTWalker::Action;
196
+ using Result = ASTWalker::PreWalkResult<Expr *>;
197
+
198
+ // Profiling for closures should be handled separately. Do not visit
199
+ // closure expressions twice.
200
+ if (isa<AbstractClosureExpr>(E) && !Parent.isNull ())
201
+ return Result (Action::SkipChildren (E));
202
+
203
+ // Expressions with no location should be skipped, but we still want to visit
204
+ // their children.
205
+ if (E->getStartLoc ().isInvalid () || E->getEndLoc ().isInvalid ())
206
+ return Result (Action::Continue (E));
207
+
208
+ return None;
194
209
}
195
210
196
211
// / Whether the children of an unmapped decl should still be walked.
@@ -262,14 +277,16 @@ struct MapRegionCounters : public ASTWalker {
262
277
return Action::Continue (S);
263
278
}
264
279
265
- PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
266
- if (skipExpr (E))
267
- return Action::Continue (E);
280
+ PreWalkAction walkToParameterListPre (ParameterList *PL) override {
281
+ // We don't walk into parameter lists. Default arguments should be visited
282
+ // directly.
283
+ // FIXME: We don't yet profile default argument generators at all.
284
+ return Action::SkipChildren ();
285
+ }
268
286
269
- // Profiling for closures should be handled separately. Do not visit
270
- // closure expressions twice.
271
- if (isa<AbstractClosureExpr>(E) && !Parent.isNull ())
272
- return Action::SkipChildren (E);
287
+ PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
288
+ if (auto SkipAction = shouldSkipExpr (E, Parent))
289
+ return *SkipAction;
273
290
274
291
// If AST visitation begins with an expression, the counter map must be
275
292
// empty. Set up a counter for the root.
@@ -648,14 +665,16 @@ struct PGOMapping : public ASTWalker {
648
665
return Action::Continue (S);
649
666
}
650
667
651
- PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
652
- if (skipExpr (E))
653
- return Action::Continue (E);
668
+ PreWalkAction walkToParameterListPre (ParameterList *PL) override {
669
+ // We don't walk into parameter lists. Default arguments should be visited
670
+ // directly.
671
+ // FIXME: We don't yet profile default argument generators at all.
672
+ return Action::SkipChildren ();
673
+ }
654
674
655
- // Profiling for closures should be handled separately. Do not visit
656
- // closure expressions twice.
657
- if (isa<AbstractClosureExpr>(E) && !Parent.isNull ())
658
- return Action::SkipChildren (E);
675
+ PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
676
+ if (auto SkipAction = shouldSkipExpr (E, Parent))
677
+ return *SkipAction;
659
678
660
679
unsigned parent = getParentCounter ();
661
680
@@ -1146,14 +1165,21 @@ struct CoverageMapping : public ASTWalker {
1146
1165
return Action::Continue (S);
1147
1166
}
1148
1167
1149
- PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
1150
- if (skipExpr (E))
1151
- return Action::Continue (E);
1168
+ PreWalkAction walkToParameterListPre (ParameterList *PL) override {
1169
+ // We don't walk into parameter lists. Default arguments should be visited
1170
+ // directly.
1171
+ // FIXME: We don't yet generate coverage for default argument generators at
1172
+ // all. This is inconsistent with property initializers, which are
1173
+ // effectively default values too. Seems like coverage doesn't offer much
1174
+ // benefit in these cases, as they're unlikely to have side effects, and
1175
+ // the values can be exercized explicitly, but we should probably at least
1176
+ // have a consistent behavior for both no matter what we choose here.
1177
+ return Action::SkipChildren ();
1178
+ }
1152
1179
1153
- // Profiling for closures should be handled separately. Do not visit
1154
- // closure expressions twice.
1155
- if (isa<AbstractClosureExpr>(E) && !Parent.isNull ())
1156
- return Action::SkipChildren (E);
1180
+ PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
1181
+ if (auto SkipAction = shouldSkipExpr (E, Parent))
1182
+ return *SkipAction;
1157
1183
1158
1184
// If we're in an 'incomplete' region, update it to include this node. This
1159
1185
// ensures we only create the region if needed.
@@ -1166,28 +1192,28 @@ struct CoverageMapping : public ASTWalker {
1166
1192
assert (RegionStack.empty () &&
1167
1193
" Mapped a region before visiting the root?" );
1168
1194
assignCounter (E);
1169
- pushRegion (E);
1170
- }
1171
-
1172
- // If there isn't an active region, we may be visiting a default
1173
- // initializer for a function argument.
1174
- if (!RegionStack.empty ()) {
1175
- if (auto *IE = dyn_cast<IfExpr>(E)) {
1176
- CounterExpr &ThenCounter = assignCounter (IE->getThenExpr ());
1177
- assignCounter (IE->getElseExpr (),
1178
- CounterExpr::Sub (getCurrentCounter (), ThenCounter));
1179
- }
1180
1195
}
1181
1196
1182
1197
if (isa<LazyInitializerExpr>(E))
1183
1198
assignCounter (E);
1184
1199
1185
- if (hasCounter (E) && !Parent. isNull () )
1200
+ if (hasCounter (E))
1186
1201
pushRegion (E);
1202
+
1203
+ assert (!RegionStack.empty () && " Must be within a region" );
1204
+
1205
+ if (auto *IE = dyn_cast<IfExpr>(E)) {
1206
+ CounterExpr &ThenCounter = assignCounter (IE->getThenExpr ());
1207
+ assignCounter (IE->getElseExpr (),
1208
+ CounterExpr::Sub (getCurrentCounter (), ThenCounter));
1209
+ }
1187
1210
return Action::Continue (E);
1188
1211
}
1189
1212
1190
1213
PostWalkResult<Expr *> walkToExprPost (Expr *E) override {
1214
+ if (shouldSkipExpr (E, Parent))
1215
+ return Action::Continue (E);
1216
+
1191
1217
if (hasCounter (E))
1192
1218
popRegions (E);
1193
1219
0 commit comments