@@ -302,6 +302,11 @@ static bool isDefer(Optional<AnyFunctionRef> enclosingFunc) {
302
302
// / same label.
303
303
static void checkLabeledStmtShadowing (
304
304
ASTContext &ctx, SourceFile *sourceFile, LabeledStmt *ls) {
305
+ // If ASTScope lookup is disabled, don't do this check at all.
306
+ // FIXME: Enable ASTScope lookup everywhere.
307
+ if (!ctx.LangOpts .EnableASTScopeLookup )
308
+ return ;
309
+
305
310
auto name = ls->getLabelInfo ().Name ;
306
311
if (name.empty () || !sourceFile || ls->getStartLoc ().isInvalid ())
307
312
return ;
@@ -355,11 +360,23 @@ static LabeledStmt *findBreakOrContinueStmtTarget(
355
360
ASTContext &ctx, SourceFile *sourceFile,
356
361
SourceLoc loc, Identifier targetName, SourceLoc targetLoc,
357
362
bool isContinue,
358
- Optional<AnyFunctionRef> enclosingFunc) {
363
+ Optional<AnyFunctionRef> enclosingFunc,
364
+ ArrayRef<LabeledStmt *> oldActiveLabeledStmts) {
359
365
TopCollection<unsigned , LabeledStmt *> labelCorrections (3 );
360
366
367
+ // Retrieve the active set of labeled statements.
368
+ // FIXME: Once everything uses ASTScope lookup, \c oldActiveLabeledStmts
369
+ // can go away.
370
+ SmallVector<LabeledStmt *, 4 > activeLabeledStmts;
371
+ if (ctx.LangOpts .EnableASTScopeLookup ) {
372
+ activeLabeledStmts = ASTScope::lookupLabeledStmts (sourceFile, loc);
373
+ } else {
374
+ activeLabeledStmts.insert (
375
+ activeLabeledStmts.end (),
376
+ oldActiveLabeledStmts.rbegin (), oldActiveLabeledStmts.rend ());
377
+ }
378
+
361
379
// Pick the nearest break target that matches the specified name.
362
- auto activeLabeledStmts = ASTScope::lookupLabeledStmts (sourceFile, loc);
363
380
if (targetName.empty ()) {
364
381
for (auto labeledStmt : activeLabeledStmts) {
365
382
// 'break' with no label looks through non-loop structures
@@ -481,7 +498,9 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
481
498
482
499
// Verify that the ASTScope-based query for active labeled statements
483
500
// is equivalent to what we have here.
484
- if (LS->getStartLoc ().isValid () && sourceFile) {
501
+ if (LS->getStartLoc ().isValid () && sourceFile &&
502
+ SC.getASTContext ().LangOpts .EnableASTScopeLookup &&
503
+ !SC.getASTContext ().Diags .hadAnyError ()) {
485
504
// The labeled statements from ASTScope lookup have the
486
505
// innermost labeled statement first, so reverse it to
487
506
// match the data structure maintained here.
@@ -858,7 +877,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
858
877
if (auto target = findBreakOrContinueStmtTarget (
859
878
getASTContext (), DC->getParentSourceFile (), S->getLoc (),
860
879
S->getTargetName (), S->getTargetLoc (), /* isContinue=*/ false ,
861
- TheFunc)) {
880
+ TheFunc, ActiveLabeledStmts )) {
862
881
S->setTarget (target);
863
882
}
864
883
@@ -869,7 +888,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
869
888
if (auto target = findBreakOrContinueStmtTarget (
870
889
getASTContext (), DC->getParentSourceFile (), S->getLoc (),
871
890
S->getTargetName (), S->getTargetLoc (), /* isContinue=*/ true ,
872
- TheFunc)) {
891
+ TheFunc, ActiveLabeledStmts )) {
873
892
S->setTarget (target);
874
893
}
875
894
@@ -878,15 +897,21 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
878
897
879
898
Stmt *visitFallthroughStmt (FallthroughStmt *S) {
880
899
auto sourceFile = DC->getParentSourceFile ();
881
- auto activeLabeledStmts = ASTScope::lookupLabeledStmts (
882
- sourceFile, S->getLoc ());
883
- auto numSwitches = llvm::count_if (activeLabeledStmts,
884
- [](LabeledStmt *labeledStmt) {
885
- return isa<SwitchStmt>(labeledStmt);
886
- });
887
- assert (numSwitches == SwitchLevel);
900
+ bool hasAnySwitches;
901
+ if (getASTContext ().LangOpts .EnableASTScopeLookup ) {
902
+ auto activeLabeledStmts = ASTScope::lookupLabeledStmts (
903
+ sourceFile, S->getLoc ());
904
+ auto numSwitches = llvm::count_if (activeLabeledStmts,
905
+ [](LabeledStmt *labeledStmt) {
906
+ return isa<SwitchStmt>(labeledStmt);
907
+ });
908
+ assert (numSwitches == SwitchLevel);
909
+ hasAnySwitches = numSwitches > 0 ;
910
+ } else {
911
+ hasAnySwitches = SwitchLevel > 0 ;
912
+ }
888
913
889
- if (!numSwitches ) {
914
+ if (!hasAnySwitches ) {
890
915
getASTContext ().Diags .diagnose (S->getLoc (),
891
916
diag::fallthrough_outside_switch);
892
917
return nullptr ;
0 commit comments