@@ -695,6 +695,9 @@ struct PGOMapping : public ASTWalker {
695
695
}
696
696
};
697
697
698
+ // / Produce coverage mapping information for a function. This involves taking
699
+ // / the counters computed by MapRegionCounters, and annotating the source with
700
+ // / regions that are defined in terms of those counters.
698
701
struct CoverageMapping : public ASTWalker {
699
702
private:
700
703
const SourceManager &SM;
@@ -976,6 +979,8 @@ struct CoverageMapping : public ASTWalker {
976
979
if (S->isImplicit () && S != ImplicitTopLevelBody)
977
980
return {true , S};
978
981
982
+ // If we're in an 'incomplete' region, update it to include this node. This
983
+ // ensures we only create the region if needed.
979
984
if (!RegionStack.empty ())
980
985
extendRegion (S);
981
986
@@ -986,7 +991,13 @@ struct CoverageMapping : public ASTWalker {
986
991
} else if (auto *IS = dyn_cast<IfStmt>(S)) {
987
992
if (auto *Cond = getConditionNode (IS->getCond ()))
988
993
assignCounter (Cond, CounterExpr::Ref (getCurrentCounter ()));
994
+
995
+ // The counter for the if statement itself tracks the number of jumps to
996
+ // it by break statements.
989
997
assignCounter (IS, CounterExpr::Zero ());
998
+
999
+ // We emit a counter for the then block, and define the else block in
1000
+ // terms of it.
990
1001
CounterExpr &ThenCounter = assignCounter (IS->getThenStmt ());
991
1002
if (IS->getElseStmt ())
992
1003
assignCounter (IS->getElseStmt (),
@@ -996,18 +1007,26 @@ struct CoverageMapping : public ASTWalker {
996
1007
assignCounter (GS->getBody ());
997
1008
998
1009
} else if (auto *WS = dyn_cast<WhileStmt>(S)) {
1010
+ // The counter for the while statement itself tracks the number of jumps
1011
+ // to it by break and continue statements.
999
1012
assignCounter (WS, CounterExpr::Zero ());
1013
+
1000
1014
if (auto *E = getConditionNode (WS->getCond ()))
1001
1015
assignCounter (E, CounterExpr::Ref (getCurrentCounter ()));
1002
1016
assignCounter (WS->getBody ());
1003
1017
1004
1018
} else if (auto *RWS = dyn_cast<RepeatWhileStmt>(S)) {
1019
+ // The counter for the while statement itself tracks the number of jumps
1020
+ // to it by break and continue statements.
1005
1021
assignCounter (RWS, CounterExpr::Zero ());
1022
+
1006
1023
CounterExpr &BodyCounter = assignCounter (RWS->getBody ());
1007
1024
assignCounter (RWS->getCond (), CounterExpr::Ref (BodyCounter));
1008
1025
RepeatWhileStack.push_back (RWS);
1009
1026
1010
1027
} else if (auto *FES = dyn_cast<ForEachStmt>(S)) {
1028
+ // The counter for the for statement itself tracks the number of jumps
1029
+ // to it by break and continue statements.
1011
1030
assignCounter (FES, CounterExpr::Zero ());
1012
1031
assignCounter (FES->getBody ());
1013
1032
@@ -1021,7 +1040,10 @@ struct CoverageMapping : public ASTWalker {
1021
1040
if (caseStmt->getParentKind () == CaseParentKind::Switch)
1022
1041
pushRegion (S);
1023
1042
} else if (auto *DS = dyn_cast<DoStmt>(S)) {
1043
+ // The counter for the do statement itself tracks the number of jumps
1044
+ // to it by break statements.
1024
1045
assignCounter (DS, CounterExpr::Zero ());
1046
+
1025
1047
assignCounter (DS->getBody (), CounterExpr::Ref (getCurrentCounter ()));
1026
1048
1027
1049
} else if (auto *DCS = dyn_cast<DoCatchStmt>(S)) {
@@ -1125,6 +1147,8 @@ struct CoverageMapping : public ASTWalker {
1125
1147
if (isa<AbstractClosureExpr>(E) && !Parent.isNull ())
1126
1148
return {false , E};
1127
1149
1150
+ // If we're in an 'incomplete' region, update it to include this node. This
1151
+ // ensures we only create the region if needed.
1128
1152
if (!RegionStack.empty ())
1129
1153
extendRegion (E);
1130
1154
0 commit comments