@@ -369,35 +369,31 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
369
369
// Parse the decl, stmt, or expression.
370
370
PreviousHadSemi = false ;
371
371
if (Tok.is (tok::pound_if) && !isStartOfSwiftDecl ()) {
372
+ SmallVector<ASTNode, 16 > activeElements;
372
373
auto IfConfigResult = parseIfConfig (
373
374
IfConfigContext::BraceItems,
374
- [&](SmallVectorImpl<ASTNode> &Elements, bool IsActive) {
375
- parseBraceItems (Elements, Kind,
375
+ [&](bool IsActive) {
376
+ SmallVector<ASTNode, 16 > elements;
377
+ parseBraceItems (elements, Kind,
376
378
IsActive
377
379
? BraceItemListKind::ActiveConditionalBlock
378
380
: BraceItemListKind::InactiveConditionalBlock,
379
381
IsFollowingGuard);
382
+
383
+ if (IsActive)
384
+ activeElements = std::move (elements);
380
385
});
381
386
if (IfConfigResult.hasCodeCompletion () && isIDEInspectionFirstPass ()) {
382
387
consumeDecl (BeginParserPosition, IsTopLevel);
383
388
return IfConfigResult;
384
389
}
385
390
BraceItemsStatus |= IfConfigResult;
386
- if (auto ICD = IfConfigResult.getPtrOrNull ()) {
387
- Result = ICD;
388
- // Add the #if block itself
389
- Entries.push_back (ICD);
390
-
391
- for (auto &Entry : ICD->getActiveClauseElements ()) {
392
- if (Entry.is <Decl *>() && isa<IfConfigDecl>(Entry.get <Decl *>()))
393
- // Don't hoist nested '#if'.
394
- continue ;
395
- Entries.push_back (Entry);
396
- }
397
- } else {
391
+ if (IfConfigResult.isError ()) {
398
392
NeedParseErrorRecovery = true ;
399
393
continue ;
400
394
}
395
+
396
+ Entries.append (activeElements);
401
397
} else if (Tok.is (tok::pound_line)) {
402
398
ParserStatus Status = parseLineDirective (true );
403
399
BraceItemsStatus |= Status;
@@ -408,7 +404,7 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
408
404
NeedParseErrorRecovery = Status.isErrorOrHasCompletion ();
409
405
} else if (isStartOfSwiftDecl ()) {
410
406
SmallVector<Decl*, 8 > TmpDecls;
411
- ParserResult<Decl> DeclResult =
407
+ ParserStatus DeclResult =
412
408
parseDecl (IsAtStartOfLineOrPreviousHadSemi,
413
409
/* IfConfigsAreDeclAttrs=*/ true , [&](Decl *D) {
414
410
TmpDecls.push_back (D);
@@ -423,16 +419,22 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
423
419
FD->setHasTopLevelLocalContextCaptures ();
424
420
});
425
421
BraceItemsStatus |= DeclResult;
426
- if (DeclResult.isParseErrorOrHasCompletion ()) {
422
+ if (DeclResult.isErrorOrHasCompletion ()) {
427
423
NeedParseErrorRecovery = true ;
428
424
if (DeclResult.hasCodeCompletion () && IsTopLevel &&
429
425
isIDEInspectionFirstPass ()) {
430
426
consumeDecl (BeginParserPosition, IsTopLevel);
431
427
return DeclResult;
432
428
}
433
429
}
434
- Result = DeclResult.getPtrOrNull ();
435
430
Entries.append (TmpDecls.begin (), TmpDecls.end ());
431
+
432
+ // HACK: If any declarations were parsed, make the last one the "result".
433
+ // We should know whether this was in an #if or not.
434
+ if (!TmpDecls.empty ()) {
435
+ Result = TmpDecls.back ();
436
+ }
437
+
436
438
} else if (IsTopLevel) {
437
439
// If this is a statement or expression at the top level of the module,
438
440
// Parse it as a child of a TopLevelCodeDecl.
@@ -2661,25 +2663,15 @@ Parser::parseStmtCases(SmallVectorImpl<ASTNode> &cases, bool IsActive) {
2661
2663
// clauses.
2662
2664
auto IfConfigResult =
2663
2665
parseIfConfig (IfConfigContext::SwitchStmt,
2664
- [&](SmallVectorImpl<ASTNode> &Elements, bool IsActive) {
2665
- parseStmtCases (Elements, IsActive);
2666
+ [&](bool IsActive) {
2667
+ SmallVector<ASTNode, 16 > elements;
2668
+ parseStmtCases (elements, IsActive);
2669
+
2670
+ if (IsActive) {
2671
+ cases.append (elements);
2672
+ }
2666
2673
});
2667
2674
Status |= IfConfigResult;
2668
- if (auto ICD = IfConfigResult.getPtrOrNull ()) {
2669
- cases.emplace_back (ICD);
2670
-
2671
- for (auto &Entry : ICD->getActiveClauseElements ()) {
2672
- if (Entry.is <Decl*>() &&
2673
- (isa<IfConfigDecl>(Entry.get <Decl*>())))
2674
- // Don't hoist nested '#if'.
2675
- continue ;
2676
-
2677
- assert ((Entry.is <Stmt*>() && isa<CaseStmt>(Entry.get <Stmt*>())) ||
2678
- (Entry.is <Decl*>() &&
2679
- isa<PoundDiagnosticDecl>(Entry.get <Decl*>())));
2680
- cases.push_back (Entry);
2681
- }
2682
- }
2683
2675
} else if (Tok.is (tok::pound_warning) || Tok.is (tok::pound_error)) {
2684
2676
auto PoundDiagnosticResult = parseDeclPoundDiagnostic ();
2685
2677
Status |= PoundDiagnosticResult;
0 commit comments