@@ -399,12 +399,9 @@ static LabeledStmt *findUnlabeledBreakOrContinueStmtTarget(
399
399
static LabeledStmt *findBreakOrContinueStmtTarget (
400
400
ASTContext &ctx, SourceFile *sourceFile,
401
401
SourceLoc loc, Identifier targetName, SourceLoc targetLoc,
402
- bool isContinue, DeclContext *dc,
403
- ArrayRef<LabeledStmt *> oldActiveLabeledStmts) {
402
+ bool isContinue, DeclContext *dc) {
404
403
405
404
// Retrieve the active set of labeled statements.
406
- // FIXME: Once everything uses ASTScope lookup, \c oldActiveLabeledStmts
407
- // can go away.
408
405
SmallVector<LabeledStmt *, 4 > activeLabeledStmts;
409
406
activeLabeledStmts = ASTScope::lookupLabeledStmts (sourceFile, loc);
410
407
@@ -603,17 +600,13 @@ static void checkFallthroughPatternBindingsAndTypes(
603
600
// / Check the correctness of a 'fallthrough' statement.
604
601
// /
605
602
// / \returns true if an error occurred.
606
- static bool checkFallthroughStmt (
607
- DeclContext *dc, FallthroughStmt *stmt,
608
- CaseStmt *oldFallthroughSource, CaseStmt *oldFallthroughDest) {
603
+ static bool checkFallthroughStmt (DeclContext *dc, FallthroughStmt *stmt) {
609
604
CaseStmt *fallthroughSource;
610
605
CaseStmt *fallthroughDest;
611
606
ASTContext &ctx = dc->getASTContext ();
612
607
auto sourceFile = dc->getParentSourceFile ();
613
608
std::tie (fallthroughSource, fallthroughDest) =
614
609
ASTScope::lookupFallthroughSourceAndDest (sourceFile, stmt->getLoc ());
615
- assert (fallthroughSource == oldFallthroughSource);
616
- assert (fallthroughDest == oldFallthroughDest);
617
610
618
611
if (!fallthroughSource) {
619
612
ctx.Diags .diagnose (stmt->getLoc (), diag::fallthrough_outside_switch);
@@ -639,88 +632,11 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
639
632
// / DC - This is the current DeclContext.
640
633
DeclContext *DC;
641
634
642
- // Scope information for control flow statements
643
- // (break, continue, fallthrough).
644
-
645
- // / The level of loop nesting. 'break' and 'continue' are valid only in scopes
646
- // / where this is greater than one.
647
- // / FIXME: Only required because EnableASTScopeLookup can be false
648
- SmallVector<LabeledStmt*, 2 > ActiveLabeledStmts;
649
-
650
- // / The destination block for a 'fallthrough' statement. Null if the switch
651
- // / scope depth is zero or if we are checking the final 'case' of the current
652
- // / switch.
653
- // / FIXME: Only required because EnableASTScopeLookup can be false
654
- CaseStmt /* nullable*/ *FallthroughSource = nullptr ;
655
- CaseStmt /* nullable*/ *FallthroughDest = nullptr ;
656
-
657
635
// / Skip type checking any elements inside 'BraceStmt', also this is
658
636
// / propagated to ConstraintSystem.
659
637
bool LeaveBraceStmtBodyUnchecked = false ;
660
638
661
639
ASTContext &getASTContext () const { return Ctx; };
662
-
663
- struct AddLabeledStmt {
664
- StmtChecker &SC;
665
- AddLabeledStmt (StmtChecker &SC, LabeledStmt *LS) : SC(SC) {
666
- // Verify that we don't have label shadowing.
667
- auto sourceFile = SC.DC ->getParentSourceFile ();
668
- checkLabeledStmtShadowing (SC.getASTContext (), sourceFile, LS);
669
-
670
- // In any case, remember that we're in this labeled statement so that
671
- // break and continue are aware of it.
672
- SC.ActiveLabeledStmts .push_back (LS);
673
-
674
- // Verify that the ASTScope-based query for active labeled statements
675
- // is equivalent to what we have here.
676
- if (LS->getStartLoc ().isValid () && sourceFile &&
677
- !SC.getASTContext ().Diags .hadAnyError () &&
678
- !SC.LeaveBraceStmtBodyUnchecked ) {
679
- // The labeled statements from ASTScope lookup have the
680
- // innermost labeled statement first, so reverse it to
681
- // match the data structure maintained here.
682
- auto activeFromASTScope = ASTScope::lookupLabeledStmts (
683
- sourceFile, LS->getStartLoc ());
684
- assert (activeFromASTScope.front () == LS);
685
- std::reverse (activeFromASTScope.begin (), activeFromASTScope.end ());
686
- if (activeFromASTScope != SC.ActiveLabeledStmts ) {
687
- llvm::errs () << " Old: " ;
688
- llvm::interleave (SC.ActiveLabeledStmts , [&](LabeledStmt *LS) {
689
- llvm::errs () << LS;
690
- }, [&] {
691
- llvm::errs () << ' ' ;
692
- });
693
- llvm::errs () << " \n New: " ;
694
- llvm::interleave (activeFromASTScope, [&](LabeledStmt *LS) {
695
- llvm::errs () << LS;
696
- }, [&] {
697
- llvm::errs () << ' ' ;
698
- });
699
- llvm::errs () << " \n " ;
700
- }
701
- assert (activeFromASTScope == SC.ActiveLabeledStmts );
702
- }
703
- }
704
- ~AddLabeledStmt () {
705
- SC.ActiveLabeledStmts .pop_back ();
706
- }
707
- };
708
-
709
- struct AddSwitchNest {
710
- StmtChecker &SC;
711
- CaseStmt *OuterFallthroughSource;
712
- CaseStmt *OuterFallthroughDest;
713
- AddSwitchNest (StmtChecker &SC)
714
- : SC(SC),
715
- OuterFallthroughSource (SC.FallthroughSource),
716
- OuterFallthroughDest(SC.FallthroughDest) {
717
- }
718
-
719
- ~AddSwitchNest () {
720
- SC.FallthroughSource = OuterFallthroughSource;
721
- SC.FallthroughDest = OuterFallthroughDest;
722
- }
723
- };
724
640
725
641
StmtChecker (DeclContext *DC) : Ctx(DC->getASTContext ()), DC(DC) { }
726
642
@@ -976,7 +892,8 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
976
892
Stmt *visitIfStmt (IfStmt *IS) {
977
893
typeCheckConditionForStatement (IS, DC);
978
894
979
- AddLabeledStmt ifNest (*this , IS);
895
+ auto sourceFile = DC->getParentSourceFile ();
896
+ checkLabeledStmtShadowing (getASTContext (), sourceFile, IS);
980
897
981
898
Stmt *S = IS->getThenStmt ();
982
899
typeCheckStmt (S);
@@ -1000,7 +917,9 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
1000
917
}
1001
918
1002
919
Stmt *visitDoStmt (DoStmt *DS) {
1003
- AddLabeledStmt loopNest (*this , DS);
920
+ auto sourceFile = DC->getParentSourceFile ();
921
+ checkLabeledStmtShadowing (getASTContext (), sourceFile, DS);
922
+
1004
923
BraceStmt *S = DS->getBody ();
1005
924
typeCheckStmt (S);
1006
925
DS->setBody (S);
@@ -1010,20 +929,22 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
1010
929
Stmt *visitWhileStmt (WhileStmt *WS) {
1011
930
typeCheckConditionForStatement (WS, DC);
1012
931
1013
- AddLabeledStmt loopNest (*this , WS);
932
+ auto sourceFile = DC->getParentSourceFile ();
933
+ checkLabeledStmtShadowing (getASTContext (), sourceFile, WS);
934
+
1014
935
Stmt *S = WS->getBody ();
1015
936
typeCheckStmt (S);
1016
937
WS->setBody (S);
1017
938
1018
939
return WS;
1019
940
}
1020
941
Stmt *visitRepeatWhileStmt (RepeatWhileStmt *RWS) {
1021
- {
1022
- AddLabeledStmt loopNest (* this , RWS);
1023
- Stmt *S = RWS-> getBody ();
1024
- typeCheckStmt (S );
1025
- RWS-> setBody (S);
1026
- }
942
+ auto sourceFile = DC-> getParentSourceFile ();
943
+ checkLabeledStmtShadowing ( getASTContext (), sourceFile , RWS);
944
+
945
+ Stmt *S = RWS-> getBody ( );
946
+ typeCheckStmt (S);
947
+ RWS-> setBody (S);
1027
948
1028
949
Expr *E = RWS->getCond ();
1029
950
TypeChecker::typeCheckCondition (E, DC);
@@ -1036,7 +957,9 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
1036
957
return nullptr ;
1037
958
1038
959
// Type-check the body of the loop.
1039
- AddLabeledStmt loopNest (*this , S);
960
+ auto sourceFile = DC->getParentSourceFile ();
961
+ checkLabeledStmtShadowing (getASTContext (), sourceFile, S);
962
+
1040
963
BraceStmt *Body = S->getBody ();
1041
964
typeCheckStmt (Body);
1042
965
S->setBody (Body);
@@ -1048,7 +971,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
1048
971
if (auto target = findBreakOrContinueStmtTarget (
1049
972
getASTContext (), DC->getParentSourceFile (), S->getLoc (),
1050
973
S->getTargetName (), S->getTargetLoc (), /* isContinue=*/ false ,
1051
- DC, ActiveLabeledStmts )) {
974
+ DC)) {
1052
975
S->setTarget (target);
1053
976
}
1054
977
@@ -1059,15 +982,15 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
1059
982
if (auto target = findBreakOrContinueStmtTarget (
1060
983
getASTContext (), DC->getParentSourceFile (), S->getLoc (),
1061
984
S->getTargetName (), S->getTargetLoc (), /* isContinue=*/ true ,
1062
- DC, ActiveLabeledStmts )) {
985
+ DC)) {
1063
986
S->setTarget (target);
1064
987
}
1065
988
1066
989
return S;
1067
990
}
1068
991
1069
992
Stmt *visitFallthroughStmt (FallthroughStmt *S) {
1070
- if (checkFallthroughStmt (DC, S, FallthroughSource, FallthroughDest ))
993
+ if (checkFallthroughStmt (DC, S))
1071
994
return nullptr ;
1072
995
1073
996
return S;
@@ -1213,13 +1136,6 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
1213
1136
for (auto i = casesBegin; i != casesEnd; ++i) {
1214
1137
auto *caseBlock = *i;
1215
1138
1216
- if (parentKind == CaseParentKind::Switch) {
1217
- // Fallthrough transfers control to the next case block. In the
1218
- // final case block, it is invalid. Only switch supports fallthrough.
1219
- FallthroughSource = caseBlock;
1220
- FallthroughDest = std::next (i) == casesEnd ? nullptr : *std::next (i);
1221
- }
1222
-
1223
1139
// Check restrictions on '@unknown'.
1224
1140
if (caseBlock->hasUnknownAttr ()) {
1225
1141
assert (parentKind == CaseParentKind::Switch &&
@@ -1246,8 +1162,8 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
1246
1162
Type subjectType = switchStmt->getSubjectExpr ()->getType ();
1247
1163
1248
1164
// Type-check the case blocks.
1249
- AddSwitchNest switchNest (* this );
1250
- AddLabeledStmt labelNest (* this , switchStmt);
1165
+ auto sourceFile = DC-> getParentSourceFile ( );
1166
+ checkLabeledStmtShadowing ( getASTContext (), sourceFile , switchStmt);
1251
1167
1252
1168
// Pre-emptively visit all Decls (#if/#warning/#error) that still exist in
1253
1169
// the list of raw cases.
@@ -1278,7 +1194,8 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
1278
1194
// The labels are in scope for both the 'do' and all of the catch
1279
1195
// clauses. This allows the user to break out of (or restart) the
1280
1196
// entire construct.
1281
- AddLabeledStmt loopNest (*this , S);
1197
+ auto sourceFile = DC->getParentSourceFile ();
1198
+ checkLabeledStmtShadowing (getASTContext (), sourceFile, S);
1282
1199
1283
1200
// Type-check the 'do' body. Type failures in here will generally
1284
1201
// not cause type failures in the 'catch' clauses.
0 commit comments