@@ -187,10 +187,25 @@ visitFunctionDecl(ASTWalker &Walker, AbstractFunctionDecl *AFD, F Func) {
187187 return ASTWalker::Action::SkipChildren ();
188188}
189189
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;
194209}
195210
196211// / Whether the children of an unmapped decl should still be walked.
@@ -262,14 +277,16 @@ struct MapRegionCounters : public ASTWalker {
262277 return Action::Continue (S);
263278 }
264279
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+ }
268286
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;
273290
274291 // If AST visitation begins with an expression, the counter map must be
275292 // empty. Set up a counter for the root.
@@ -648,14 +665,16 @@ struct PGOMapping : public ASTWalker {
648665 return Action::Continue (S);
649666 }
650667
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+ }
654674
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;
659678
660679 unsigned parent = getParentCounter ();
661680
@@ -1146,14 +1165,21 @@ struct CoverageMapping : public ASTWalker {
11461165 return Action::Continue (S);
11471166 }
11481167
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+ }
11521179
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;
11571183
11581184 // If we're in an 'incomplete' region, update it to include this node. This
11591185 // ensures we only create the region if needed.
@@ -1166,28 +1192,28 @@ struct CoverageMapping : public ASTWalker {
11661192 assert (RegionStack.empty () &&
11671193 " Mapped a region before visiting the root?" );
11681194 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- }
11801195 }
11811196
11821197 if (isa<LazyInitializerExpr>(E))
11831198 assignCounter (E);
11841199
1185- if (hasCounter (E) && !Parent. isNull () )
1200+ if (hasCounter (E))
11861201 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+ }
11871210 return Action::Continue (E);
11881211 }
11891212
11901213 PostWalkResult<Expr *> walkToExprPost (Expr *E) override {
1214+ if (shouldSkipExpr (E, Parent))
1215+ return Action::Continue (E);
1216+
11911217 if (hasCounter (E))
11921218 popRegions (E);
11931219
0 commit comments