Skip to content

Commit 5cd7404

Browse files
authored
Merge pull request #21879 from slavapestov/fix-delayed-member-parsing
Refactor delayed member parsing and fix a bug
2 parents a0e82bb + 482f73c commit 5cd7404

File tree

11 files changed

+152
-151
lines changed

11 files changed

+152
-151
lines changed

include/swift/Frontend/Frontend.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -614,8 +614,7 @@ class CompilerInstance {
614614

615615
private:
616616
void createREPLFile(const ImplicitImports &implicitImports);
617-
std::unique_ptr<DelayedParsingCallbacks>
618-
computeDelayedParsingCallback(bool isPrimary);
617+
std::unique_ptr<DelayedParsingCallbacks> computeDelayedParsingCallback();
619618

620619
void addMainFileToModule(const ImplicitImports &implicitImports);
621620

@@ -626,15 +625,13 @@ class CompilerInstance {
626625
void parseLibraryFile(unsigned BufferID,
627626
const ImplicitImports &implicitImports,
628627
PersistentParserState &PersistentState,
629-
DelayedParsingCallbacks *PrimaryDelayedCB,
630-
DelayedParsingCallbacks *SecondaryDelayedCB);
628+
DelayedParsingCallbacks *DelayedCB);
631629

632630
/// Return true if had load error
633631
bool
634632
parsePartialModulesAndLibraryFiles(const ImplicitImports &implicitImports,
635633
PersistentParserState &PersistentState,
636-
DelayedParsingCallbacks *PrimaryDelayedCB,
637-
DelayedParsingCallbacks *SecondaryDelayedCB);
634+
DelayedParsingCallbacks *DelayedCB);
638635

639636
OptionSet<TypeCheckingFlags> computeTypeCheckingOptions();
640637

include/swift/Parse/DelayedParsingCallbacks.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,6 @@ class DelayedParsingCallbacks {
3535
SourceRange BodyRange) = 0;
3636
};
3737

38-
class AlwaysDelayedCallbacks : public DelayedParsingCallbacks {
39-
bool shouldDelayFunctionBodyParsing(Parser &TheParser,
40-
AbstractFunctionDecl *AFD,
41-
const DeclAttributes &Attrs,
42-
SourceRange BodyRange) override {
43-
return true;
44-
}
45-
};
46-
4738
/// Implementation of callbacks that guide the parser in delayed
4839
/// parsing for code completion.
4940
class CodeCompleteDelayedCallbacks : public DelayedParsingCallbacks {

include/swift/Parse/Parser.h

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,9 @@ class Parser {
165165

166166
DelayedParsingCallbacks *DelayedParseCB = nullptr;
167167

168-
bool isDelayedParsingEnabled() const { return DelayedParseCB != nullptr; }
168+
bool isDelayedParsingEnabled() const {
169+
return DelayBodyParsing || DelayedParseCB != nullptr;
170+
}
169171

170172
void setDelayedParsingCallbacks(DelayedParsingCallbacks *DelayedParseCB) {
171173
this->DelayedParseCB = DelayedParseCB;
@@ -207,8 +209,15 @@ class Parser {
207209
/// Always empty if !SF.shouldBuildSyntaxTree().
208210
ParsedTrivia TrailingTrivia;
209211

210-
/// Whether we should disable delayed parsing.
211-
bool DisableDelayedParsing;
212+
/// Whether we should delay parsing nominal type and extension bodies,
213+
/// and skip function bodies.
214+
///
215+
/// This is false in primary files, since we want to type check all
216+
/// declarations and function bodies.
217+
///
218+
/// This is true for non-primary files, where declarations only need to be
219+
/// lazily parsed and type checked.
220+
bool DelayBodyParsing;
212221

213222
/// The receiver to collect all consumed tokens.
214223
ConsumeTokenReceiver *TokReceiver;
@@ -357,16 +366,16 @@ class Parser {
357366
SILParserTUStateBase *SIL,
358367
PersistentParserState *PersistentState,
359368
std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
360-
bool DisableDelayedParsing = false);
369+
bool DelayBodyParsing = true);
361370
Parser(unsigned BufferID, SourceFile &SF, SILParserTUStateBase *SIL,
362371
PersistentParserState *PersistentState = nullptr,
363372
std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
364-
bool DisableDelayedParsing = false);
373+
bool DelayBodyParsing = true);
365374
Parser(std::unique_ptr<Lexer> Lex, SourceFile &SF,
366375
SILParserTUStateBase *SIL = nullptr,
367376
PersistentParserState *PersistentState = nullptr,
368377
std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
369-
bool DisableDelayedParsing = false);
378+
bool DelayBodyParsing = true);
370379
~Parser();
371380

372381
bool isInSILMode() const { return SIL != nullptr; }
@@ -798,6 +807,13 @@ class Parser {
798807

799808
void parseDeclListDelayed(IterableDeclContext *IDC);
800809

810+
bool canDelayMemberDeclParsing();
811+
812+
bool delayParsingDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
813+
SourceLoc PosBeforeLB,
814+
ParseDeclOptions Options,
815+
IterableDeclContext *IDC);
816+
801817
ParserResult<TypeDecl> parseDeclTypeAlias(ParseDeclOptions Flags,
802818
DeclAttributes &Attributes);
803819

@@ -894,7 +910,7 @@ class Parser {
894910
llvm::function_ref<void(Decl*)> handler);
895911
bool parseDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
896912
Diag<> ErrorDiag, ParseDeclOptions Options,
897-
llvm::function_ref<void(Decl*)> handler);
913+
IterableDeclContext *IDC);
898914
ParserResult<ExtensionDecl> parseDeclExtension(ParseDeclOptions Flags,
899915
DeclAttributes &Attributes);
900916
ParserResult<EnumDecl> parseDeclEnum(ParseDeclOptions Flags,
@@ -1428,8 +1444,6 @@ class Parser {
14281444
parsePlatformVersionConstraintSpec();
14291445
ParserResult<PlatformAgnosticVersionConstraintAvailabilitySpec>
14301446
parsePlatformAgnosticVersionConstraintSpec();
1431-
1432-
bool canDelayMemberDeclParsing();
14331447
};
14341448

14351449
/// Describes a parsed declaration name.

include/swift/Subsystems.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ namespace swift {
122122
SILParserState *SIL = nullptr,
123123
PersistentParserState *PersistentState = nullptr,
124124
DelayedParsingCallbacks *DelayedParseCB = nullptr,
125-
bool DisableDelayedParsing = false);
125+
bool DelayBodyParsing = true);
126126

127127
/// Parse a single buffer into the given source file, until the full source
128128
/// contents are parsed.
@@ -131,7 +131,7 @@ namespace swift {
131131
bool parseIntoSourceFileFull(SourceFile &SF, unsigned BufferID,
132132
PersistentParserState *PersistentState = nullptr,
133133
DelayedParsingCallbacks *DelayedParseCB = nullptr,
134-
bool DisableDelayedParsing = false);
134+
bool DelayBodyParsing = true);
135135

136136
/// Finish the parsing by going over the nodes that were delayed
137137
/// during the first parsing pass.

lib/AST/Decl.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3547,7 +3547,6 @@ void ClassDecl::addImplicitDestructor() {
35473547
// Create an empty body for the destructor.
35483548
DD->setBody(BraceStmt::create(ctx, getLoc(), { }, getLoc(), true));
35493549
addMember(DD);
3550-
setHasDestructor();
35513550

35523551
// Propagate access control and versioned-ness.
35533552
DD->copyFormalAccessFrom(this, /*sourceIsParentContext*/true);

lib/AST/NameLookup.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,11 @@ void MemberLookupTable::updateLookupTable(NominalTypeDecl *nominal) {
14371437
}
14381438

14391439
void NominalTypeDecl::addedMember(Decl *member) {
1440+
// Remember if we added a destructor.
1441+
if (auto *CD = dyn_cast<ClassDecl>(this))
1442+
if (isa<DestructorDecl>(member))
1443+
CD->setHasDestructor();
1444+
14401445
// If we have a lookup table, add the new member to it.
14411446
if (LookupTable.getPointer()) {
14421447
LookupTable.getPointer()->addMember(member);

lib/Frontend/Frontend.cpp

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -735,12 +735,10 @@ void CompilerInstance::createREPLFile(const ImplicitImports &implicitImports) {
735735
}
736736

737737
std::unique_ptr<DelayedParsingCallbacks>
738-
CompilerInstance::computeDelayedParsingCallback(bool isPrimary) {
738+
CompilerInstance::computeDelayedParsingCallback() {
739739
if (Invocation.isCodeCompletion())
740740
return llvm::make_unique<CodeCompleteDelayedCallbacks>(
741741
SourceMgr.getCodeCompletionLoc());
742-
if (!isPrimary)
743-
return llvm::make_unique<AlwaysDelayedCallbacks>();
744742
return nullptr;
745743
}
746744

@@ -754,22 +752,13 @@ void CompilerInstance::addMainFileToModule(
754752
void CompilerInstance::parseAndCheckTypesUpTo(
755753
const ImplicitImports &implicitImports, SourceFile::ASTStage_t limitStage) {
756754
FrontendStatsTracer tracer(Context->Stats, "parse-and-check-types");
757-
// Delayed parsing callback for the primary file, or all files
758-
// in non-WMO mode.
759-
std::unique_ptr<DelayedParsingCallbacks> PrimaryDelayedCB{
760-
computeDelayedParsingCallback(true)};
761-
762-
// Delayed parsing callback for non-primary files. Not used in
763-
// WMO mode.
764-
std::unique_ptr<DelayedParsingCallbacks> SecondaryDelayedCB{
765-
computeDelayedParsingCallback(false)};
755+
std::unique_ptr<DelayedParsingCallbacks> DelayedCB{
756+
computeDelayedParsingCallback()};
766757

767758
PersistentParserState PersistentState(getASTContext());
768759

769760
bool hadLoadError = parsePartialModulesAndLibraryFiles(
770-
implicitImports, PersistentState,
771-
PrimaryDelayedCB.get(),
772-
SecondaryDelayedCB.get());
761+
implicitImports, PersistentState, DelayedCB.get());
773762
if (Invocation.isCodeCompletion()) {
774763
// When we are doing code completion, make sure to emit at least one
775764
// diagnostic, so that ASTContext is marked as erroneous. In this case
@@ -788,7 +777,7 @@ void CompilerInstance::parseAndCheckTypesUpTo(
788777
// interwined.
789778
if (MainBufferID != NO_SUCH_BUFFER) {
790779
parseAndTypeCheckMainFileUpTo(limitStage, PersistentState,
791-
PrimaryDelayedCB.get(), TypeCheckOptions);
780+
DelayedCB.get(), TypeCheckOptions);
792781
}
793782

794783
assert(llvm::all_of(MainModule->getFiles(), [](const FileUnit *File) -> bool {
@@ -829,16 +818,14 @@ void CompilerInstance::parseAndCheckTypesUpTo(
829818
void CompilerInstance::parseLibraryFile(
830819
unsigned BufferID, const ImplicitImports &implicitImports,
831820
PersistentParserState &PersistentState,
832-
DelayedParsingCallbacks *PrimaryDelayedCB,
833-
DelayedParsingCallbacks *SecondaryDelayedCB) {
821+
DelayedParsingCallbacks *DelayedCB) {
834822
FrontendStatsTracer tracer(Context->Stats, "parse-library-file");
835823

836824
auto *NextInput = createSourceFileForMainModule(
837825
SourceFileKind::Library, implicitImports.kind, BufferID);
838826
addAdditionalInitialImportsTo(NextInput, implicitImports);
839827

840828
auto IsPrimary = isWholeModuleCompilation() || isPrimaryInput(BufferID);
841-
auto *DelayedCB = IsPrimary ? PrimaryDelayedCB : SecondaryDelayedCB;
842829

843830
auto &Diags = NextInput->getASTContext().Diags;
844831
auto DidSuppressWarnings = Diags.getSuppressWarnings();
@@ -849,7 +836,7 @@ void CompilerInstance::parseLibraryFile(
849836
// Parser may stop at some erroneous constructions like #else, #endif
850837
// or '}' in some cases, continue parsing until we are done
851838
parseIntoSourceFile(*NextInput, BufferID, &Done, nullptr, &PersistentState,
852-
DelayedCB);
839+
DelayedCB, /*DelayedBodyParsing=*/!IsPrimary);
853840
} while (!Done);
854841

855842
Diags.setSuppressWarnings(DidSuppressWarnings);
@@ -878,8 +865,7 @@ OptionSet<TypeCheckingFlags> CompilerInstance::computeTypeCheckingOptions() {
878865
bool CompilerInstance::parsePartialModulesAndLibraryFiles(
879866
const ImplicitImports &implicitImports,
880867
PersistentParserState &PersistentState,
881-
DelayedParsingCallbacks *PrimaryDelayedCB,
882-
DelayedParsingCallbacks *SecondaryDelayedCB) {
868+
DelayedParsingCallbacks *DelayedCB) {
883869
FrontendStatsTracer tracer(Context->Stats,
884870
"parse-partial-modules-and-library-files");
885871
bool hadLoadError = false;
@@ -894,8 +880,7 @@ bool CompilerInstance::parsePartialModulesAndLibraryFiles(
894880
// Then parse all the library files.
895881
for (auto BufferID : InputSourceCodeBufferIDs) {
896882
if (BufferID != MainBufferID) {
897-
parseLibraryFile(BufferID, implicitImports, PersistentState,
898-
PrimaryDelayedCB, SecondaryDelayedCB);
883+
parseLibraryFile(BufferID, implicitImports, PersistentState, DelayedCB);
899884
}
900885
}
901886
return hadLoadError;
@@ -928,7 +913,7 @@ void CompilerInstance::parseAndTypeCheckMainFileUpTo(
928913
// with 'sil' definitions.
929914
parseIntoSourceFile(MainFile, MainFile.getBufferID().getValue(), &Done,
930915
TheSILModule ? &SILContext : nullptr, &PersistentState,
931-
DelayedParseCB);
916+
DelayedParseCB, /*DelayedBodyParsing=*/false);
932917

933918
if (mainIsPrimary && (Done || CurTUElem < MainFile.Decls.size())) {
934919
switch (LimitStage) {
@@ -1055,11 +1040,14 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
10551040
if (BufferID == MainBufferID)
10561041
continue;
10571042

1043+
auto IsPrimary = isWholeModuleCompilation() || isPrimaryInput(BufferID);
1044+
10581045
SourceFile *NextInput = createSourceFileForMainModule(
10591046
SourceFileKind::Library, SourceFile::ImplicitModuleImportKind::None,
10601047
BufferID);
10611048

1062-
parseIntoSourceFileFull(*NextInput, BufferID, &PersistentState);
1049+
parseIntoSourceFileFull(*NextInput, BufferID, &PersistentState,
1050+
nullptr, /*DelayBodyParsing=*/!IsPrimary);
10631051
}
10641052

10651053
// Now parse the main file.
@@ -1069,7 +1057,8 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals,
10691057
MainFile.SyntaxParsingCache = Invocation.getMainFileSyntaxParsingCache();
10701058

10711059
parseIntoSourceFileFull(MainFile, MainFile.getBufferID().getValue(),
1072-
&PersistentState);
1060+
&PersistentState, nullptr,
1061+
/*DelayBodyParsing=*/false);
10731062
}
10741063

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

0 commit comments

Comments
 (0)