Skip to content

Commit 2724cf6

Browse files
committed
[Parse] Check the SourceFile to see if bodies can be delayed
Remove the `DelayBodyParsing` flag from the parser and instead query the source file.
1 parent 2ec619c commit 2724cf6

File tree

8 files changed

+53
-62
lines changed

8 files changed

+53
-62
lines changed

include/swift/AST/SourceFile.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,10 @@ class SourceFile final : public FileUnit {
569569

570570
bool isSuitableForASTScopes() const { return canBeParsedInFull(); }
571571

572+
/// Whether the bodies of types and functions within this file can be lazily
573+
/// parsed.
574+
bool hasDelayedBodyParsing() const;
575+
572576
syntax::SourceFileSyntax getSyntaxRoot() const;
573577
void setSyntaxRoot(syntax::SourceFileSyntax &&Root);
574578
bool hasSyntaxRoot() const;

include/swift/Parse/Parser.h

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,9 @@ class Parser {
173173

174174
LocalContext *CurLocalContext = nullptr;
175175

176-
bool isDelayedParsingEnabled() const {
177-
return DelayBodyParsing || isCodeCompletionFirstPass();
178-
}
176+
/// Whether we should delay parsing nominal type, extension, and function
177+
/// bodies.
178+
bool isDelayedParsingEnabled() const;
179179

180180
void setCodeCompletionCallbacks(CodeCompletionCallbacks *Callbacks) {
181181
CodeCompletion = Callbacks;
@@ -213,16 +213,6 @@ class Parser {
213213
/// Always empty if !SF.shouldBuildSyntaxTree().
214214
ParsedTrivia TrailingTrivia;
215215

216-
/// Whether we should delay parsing nominal type and extension bodies,
217-
/// and skip function bodies.
218-
///
219-
/// This is false in primary files, since we want to type check all
220-
/// declarations and function bodies.
221-
///
222-
/// This is true for non-primary files, where declarations only need to be
223-
/// lazily parsed and type checked.
224-
bool DelayBodyParsing;
225-
226216
/// Whether to evaluate the conditions of #if decls, meaning that the bodies
227217
/// of any active clauses are hoisted such that they become sibling nodes with
228218
/// the #if decl.
@@ -408,16 +398,16 @@ class Parser {
408398
SILParserTUStateBase *SIL,
409399
PersistentParserState *PersistentState,
410400
std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
411-
bool DelayBodyParsing = true, bool EvaluateConditionals = true);
401+
bool EvaluateConditionals = true);
412402
Parser(unsigned BufferID, SourceFile &SF, SILParserTUStateBase *SIL,
413403
PersistentParserState *PersistentState = nullptr,
414404
std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
415-
bool DelayBodyParsing = true, bool EvaluateConditionals = true);
405+
bool EvaluateConditionals = true);
416406
Parser(std::unique_ptr<Lexer> Lex, SourceFile &SF,
417407
SILParserTUStateBase *SIL = nullptr,
418408
PersistentParserState *PersistentState = nullptr,
419409
std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
420-
bool DelayBodyParsing = true, bool EvaluateConditionals = true);
410+
bool EvaluateConditionals = true);
421411
~Parser();
422412

423413
/// Returns true if the buffer being parsed is allowed to contain SIL.

include/swift/Subsystems.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,7 @@ namespace swift {
108108
/// \param SF The file within the module being parsed.
109109
///
110110
/// \param BufferID The buffer to parse from.
111-
///
112-
/// \param DelayBodyParsing Whether parsing of type and function bodies can be
113-
/// delayed.
114111
void parseIntoSourceFile(SourceFile &SF, unsigned BufferID,
115-
bool DelayBodyParsing = true,
116112
bool EvaluateConditionals = true);
117113

118114
/// Parse a source file's SIL declarations into a given SIL module.

lib/AST/Module.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1954,6 +1954,23 @@ bool SourceFile::canBeParsedInFull() const {
19541954
llvm_unreachable("unhandled kind");
19551955
}
19561956

1957+
bool SourceFile::hasDelayedBodyParsing() const {
1958+
if (ParsingOpts.contains(ParsingFlags::DisableDelayedBodies))
1959+
return false;
1960+
1961+
// Not supported right now.
1962+
if (Kind == SourceFileKind::REPL || Kind == SourceFileKind::SIL)
1963+
return false;
1964+
if (hasInterfaceHash())
1965+
return false;
1966+
if (shouldCollectToken())
1967+
return false;
1968+
if (shouldBuildSyntaxTree())
1969+
return false;
1970+
1971+
return true;
1972+
}
1973+
19571974
bool FileUnit::walk(ASTWalker &walker) {
19581975
SmallVector<Decl *, 64> Decls;
19591976
getTopLevelDecls(Decls);

lib/Frontend/Frontend.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,7 @@ void CompilerInstance::parseLibraryFile(
976976
auto DidSuppressWarnings = Diags.getSuppressWarnings();
977977
Diags.setSuppressWarnings(DidSuppressWarnings || !IsPrimary);
978978

979-
parseIntoSourceFile(*NextInput, BufferID, /*DelayedBodyParsing=*/!IsPrimary);
979+
parseIntoSourceFile(*NextInput, BufferID);
980980

981981
Diags.setSuppressWarnings(DidSuppressWarnings);
982982

@@ -1023,8 +1023,7 @@ void CompilerInstance::parseAndTypeCheckMainFileUpTo(
10231023
Diags.setSuppressWarnings(DidSuppressWarnings || !mainIsPrimary);
10241024

10251025
// Parse the Swift decls into the source file.
1026-
parseIntoSourceFile(MainFile, MainBufferID,
1027-
/*delayBodyParsing*/ !mainIsPrimary);
1026+
parseIntoSourceFile(MainFile, MainBufferID);
10281027

10291028
// For a primary, also perform type checking if needed. Otherwise, just do
10301029
// name binding.
@@ -1139,14 +1138,6 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
11391138
MainBufferID, parsingOpts);
11401139
}
11411140

1142-
auto shouldDelayBodies = [&](unsigned bufferID) -> bool {
1143-
if (!CanDelayBodies)
1144-
return false;
1145-
1146-
// Don't delay bodies in whole module mode or for primary files.
1147-
return !(isWholeModuleCompilation() || isPrimaryInput(bufferID));
1148-
};
1149-
11501141
// Parse all the library files.
11511142
for (auto BufferID : InputSourceCodeBufferIDs) {
11521143
if (BufferID == MainBufferID)
@@ -1156,8 +1147,7 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
11561147
SourceFileKind::Library, SourceFile::ImplicitModuleImportKind::None,
11571148
BufferID, parsingOpts);
11581149

1159-
parseIntoSourceFile(*NextInput, BufferID, shouldDelayBodies(BufferID),
1160-
EvaluateConditionals);
1150+
parseIntoSourceFile(*NextInput, BufferID, EvaluateConditionals);
11611151
}
11621152

11631153
// Now parse the main file.
@@ -1167,8 +1157,7 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
11671157
MainFile.SyntaxParsingCache = Invocation.getMainFileSyntaxParsingCache();
11681158
assert(MainBufferID == MainFile.getBufferID());
11691159

1170-
parseIntoSourceFile(MainFile, MainBufferID, shouldDelayBodies(MainBufferID),
1171-
EvaluateConditionals);
1160+
parseIntoSourceFile(MainFile, MainBufferID, EvaluateConditionals);
11721161
}
11731162

11741163
assert(Context->LoadedModules.size() == 1 &&

lib/Parse/ParseDecl.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4569,7 +4569,7 @@ Parser::parseDeclList(SourceLoc LBLoc, SourceLoc &RBLoc, Diag<> ErrorDiag,
45694569
bool Parser::canDelayMemberDeclParsing(bool &HasOperatorDeclarations,
45704570
bool &HasNestedClassDeclarations) {
45714571
// If explicitly disabled, respect the flag.
4572-
if (!DelayBodyParsing)
4572+
if (!isDelayedParsingEnabled())
45734573
return false;
45744574
// Recovering parser status later for #sourceLocation is not-trivial and
45754575
// it may not worth it.
@@ -6449,7 +6449,10 @@ void Parser::parseAbstractFunctionBody(AbstractFunctionDecl *AFD) {
64496449

64506450
llvm::SaveAndRestore<NullablePtr<llvm::MD5>> T(CurrentTokenHash, nullptr);
64516451

6452-
if (isDelayedParsingEnabled()) {
6452+
// If we can delay parsing this body, or this is the first pass of code
6453+
// completion, skip until the end. If we encounter a code completion token
6454+
// while skipping, we'll make a note of it.
6455+
if (isDelayedParsingEnabled() || isCodeCompletionFirstPass()) {
64536456
consumeAbstractFunctionBody(AFD, AFD->getAttrs());
64546457
return;
64556458
}

lib/Parse/Parser.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,6 @@ void Parser::performCodeCompletionSecondPassImpl(
151151
// Set the parser position to the start of the delayed decl or the body.
152152
restoreParserPosition(getParserPosition(startLoc, prevLoc));
153153

154-
// Do not delay parsing in the second pass.
155-
llvm::SaveAndRestore<bool> DisableDelayedBody(DelayBodyParsing, false);
156-
157154
// Re-enter the lexical scope.
158155
Scope S(this, info.takeScope());
159156

@@ -366,15 +363,15 @@ static LexerMode sourceFileKindToLexerMode(SourceFileKind kind) {
366363
Parser::Parser(unsigned BufferID, SourceFile &SF, SILParserTUStateBase *SIL,
367364
PersistentParserState *PersistentState,
368365
std::shared_ptr<SyntaxParseActions> SPActions,
369-
bool DelayBodyParsing, bool EvaluateConditionals)
366+
bool EvaluateConditionals)
370367
: Parser(BufferID, SF, &SF.getASTContext().Diags, SIL, PersistentState,
371-
std::move(SPActions), DelayBodyParsing, EvaluateConditionals) {}
368+
std::move(SPActions), EvaluateConditionals) {}
372369

373370
Parser::Parser(unsigned BufferID, SourceFile &SF, DiagnosticEngine* LexerDiags,
374371
SILParserTUStateBase *SIL,
375372
PersistentParserState *PersistentState,
376373
std::shared_ptr<SyntaxParseActions> SPActions,
377-
bool DelayBodyParsing, bool EvaluateConditionals)
374+
bool EvaluateConditionals)
378375
: Parser(
379376
std::unique_ptr<Lexer>(new Lexer(
380377
SF.getASTContext().LangOpts, SF.getASTContext().SourceMgr,
@@ -389,7 +386,7 @@ Parser::Parser(unsigned BufferID, SourceFile &SF, DiagnosticEngine* LexerDiags,
389386
SF.shouldBuildSyntaxTree()
390387
? TriviaRetentionMode::WithTrivia
391388
: TriviaRetentionMode::WithoutTrivia)),
392-
SF, SIL, PersistentState, std::move(SPActions), DelayBodyParsing,
389+
SF, SIL, PersistentState, std::move(SPActions),
393390
EvaluateConditionals) {}
394391

395392
namespace {
@@ -511,7 +508,7 @@ Parser::Parser(std::unique_ptr<Lexer> Lex, SourceFile &SF,
511508
SILParserTUStateBase *SIL,
512509
PersistentParserState *PersistentState,
513510
std::shared_ptr<SyntaxParseActions> SPActions,
514-
bool DelayBodyParsing, bool EvaluateConditionals)
511+
bool EvaluateConditionals)
515512
: SourceMgr(SF.getASTContext().SourceMgr),
516513
Diags(SF.getASTContext().Diags),
517514
SF(SF),
@@ -520,7 +517,6 @@ Parser::Parser(std::unique_ptr<Lexer> Lex, SourceFile &SF,
520517
CurDeclContext(&SF),
521518
Context(SF.getASTContext()),
522519
CurrentTokenHash(SF.getInterfaceHashPtr()),
523-
DelayBodyParsing(DelayBodyParsing),
524520
EvaluateConditionals(EvaluateConditionals),
525521
TokReceiver(SF.shouldCollectToken() ?
526522
new TokenRecorder(SF, L->getBufferID()) :
@@ -547,6 +543,14 @@ Parser::~Parser() {
547543

548544
bool Parser::isInSILMode() const { return SF.Kind == SourceFileKind::SIL; }
549545

546+
bool Parser::isDelayedParsingEnabled() const {
547+
// Do not delay parsing during code completion's second pass.
548+
if (CodeCompletion)
549+
return false;
550+
551+
return SF.hasDelayedBodyParsing();
552+
}
553+
550554
bool Parser::allowTopLevelCode() const {
551555
return SF.isScriptMode();
552556
}
@@ -1201,8 +1205,7 @@ ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned Buffer
12011205

12021206
Impl.SF->SyntaxParsingCache = SyntaxCache;
12031207
Impl.TheParser.reset(new Parser(BufferID, *Impl.SF, /*SIL=*/nullptr,
1204-
/*PersistentState=*/nullptr, Impl.SPActions,
1205-
/*DelayBodyParsing=*/false));
1208+
/*PersistentState=*/nullptr, Impl.SPActions));
12061209
}
12071210

12081211
ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID,
@@ -1219,7 +1222,7 @@ ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned Buffer
12191222
TriviaRetentionMode::WithoutTrivia,
12201223
Offset, EndOffset));
12211224
Impl.TheParser.reset(new Parser(std::move(Lex), *Impl.SF, /*SIL=*/nullptr,
1222-
/*PersistentState=*/nullptr, Impl.SPActions, /*DelayBodyParsing=*/false));
1225+
/*PersistentState=*/nullptr, Impl.SPActions));
12231226
}
12241227

12251228
ParserUnit::~ParserUnit() {

lib/ParseSIL/ParseSIL.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ static void deletePersistentParserState(PersistentParserState *state) {
120120
}
121121

122122
void swift::parseIntoSourceFile(SourceFile &SF, unsigned int BufferID,
123-
bool DelayBodyParsing,
124123
bool EvaluateConditionals) {
125124
auto &ctx = SF.getASTContext();
126125
std::shared_ptr<SyntaxTreeCreator> STreeCreator;
@@ -130,16 +129,6 @@ void swift::parseIntoSourceFile(SourceFile &SF, unsigned int BufferID,
130129
SF.SyntaxParsingCache, SF.getASTContext().getSyntaxArena());
131130
}
132131

133-
// Not supported right now.
134-
if (SF.Kind == SourceFileKind::REPL)
135-
DelayBodyParsing = false;
136-
if (SF.hasInterfaceHash())
137-
DelayBodyParsing = false;
138-
if (SF.shouldCollectToken())
139-
DelayBodyParsing = false;
140-
if (SF.shouldBuildSyntaxTree())
141-
DelayBodyParsing = false;
142-
143132
// If this buffer is for code completion, hook up the state needed by its
144133
// second pass.
145134
PersistentParserState *state = nullptr;
@@ -150,7 +139,7 @@ void swift::parseIntoSourceFile(SourceFile &SF, unsigned int BufferID,
150139

151140
FrontendStatsTracer tracer(SF.getASTContext().Stats,
152141
"Parsing");
153-
Parser P(BufferID, SF, /*SIL*/ nullptr, state, STreeCreator, DelayBodyParsing,
142+
Parser P(BufferID, SF, /*SIL*/ nullptr, state, STreeCreator,
154143
EvaluateConditionals);
155144
PrettyStackTraceParser StackTrace(P);
156145

@@ -172,7 +161,7 @@ void swift::parseSourceFileSIL(SourceFile &SF, SILParserState *sil) {
172161
"Parsing SIL");
173162
Parser parser(*bufferID, SF, sil->Impl.get(),
174163
/*persistentParserState*/ nullptr,
175-
/*syntaxTreeCreator*/ nullptr, /*delayBodyParsing*/ false);
164+
/*syntaxTreeCreator*/ nullptr);
176165
PrettyStackTraceParser StackTrace(parser);
177166
parser.parseTopLevelSIL();
178167
}

0 commit comments

Comments
 (0)