Skip to content

Commit 6d2d668

Browse files
authored
Merge pull request #32418 from CodaFi/load-time-lift
[NFC] Hide LoadedModules From Clients of ASTContext
2 parents 260b6a1 + 057097a commit 6d2d668

File tree

10 files changed

+58
-25
lines changed

10 files changed

+58
-25
lines changed

include/swift/AST/ASTContext.h

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,6 @@ class ASTContext final {
254254
/// The request-evaluator that is used to process various requests.
255255
Evaluator evaluator;
256256

257-
/// The set of top-level modules we have loaded.
258-
/// This map is used for iteration, therefore it's a MapVector and not a
259-
/// DenseMap.
260-
llvm::MapVector<Identifier, ModuleDecl*> LoadedModules;
261-
262257
/// The builtin module.
263258
ModuleDecl * const TheBuiltinModule;
264259

@@ -787,8 +782,24 @@ class ASTContext final {
787782
/// The loader is owned by the AST context.
788783
ClangModuleLoader *getDWARFModuleLoader() const;
789784

785+
public:
790786
namelookup::ImportCache &getImportCache() const;
791787

788+
/// Returns an iterator over the modules that are known by this context
789+
/// to be loaded.
790+
///
791+
/// Iteration order is guaranteed to match the order in which
792+
/// \c addLoadedModule was called to register the loaded module
793+
/// with this context.
794+
iterator_range<llvm::MapVector<Identifier, ModuleDecl *>::const_iterator>
795+
getLoadedModules() const;
796+
797+
/// Returns the number of loaded modules known by this context to be loaded.
798+
unsigned getNumLoadedModules() const {
799+
auto eltRange = getLoadedModules();
800+
return std::distance(eltRange.begin(), eltRange.end());
801+
}
802+
792803
/// Asks every module loader to verify the ASTs it has loaded.
793804
///
794805
/// Does nothing in non-asserts (NDEBUG) builds.
@@ -828,6 +839,11 @@ class ASTContext final {
828839
return const_cast<ASTContext *>(this)->getStdlibModule(false);
829840
}
830841

842+
/// Insert an externally-sourced module into the set of known loaded modules
843+
/// in this context.
844+
void addLoadedModule(ModuleDecl *M);
845+
846+
public:
831847
/// Retrieve the current generation number, which reflects the
832848
/// number of times a module import has caused mass invalidation of
833849
/// lookup tables.

lib/AST/ASTContext.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ struct ASTContext::Implementation {
156156
/// The set of cleanups to be called when the ASTContext is destroyed.
157157
std::vector<std::function<void(void)>> Cleanups;
158158

159+
/// The set of top-level modules we have loaded.
160+
/// This map is used for iteration, therefore it's a MapVector and not a
161+
/// DenseMap.
162+
llvm::MapVector<Identifier, ModuleDecl *> LoadedModules;
163+
159164
// FIXME: This is a StringMap rather than a StringSet because StringSet
160165
// doesn't allow passing in a pre-existing allocator.
161166
llvm::StringMap<Identifier::Aligner, llvm::BumpPtrAllocator&>
@@ -1538,8 +1543,18 @@ ModuleDecl *ASTContext::getLoadedModule(
15381543
return nullptr;
15391544
}
15401545

1546+
iterator_range<llvm::MapVector<Identifier, ModuleDecl *>::const_iterator>
1547+
ASTContext::getLoadedModules() const {
1548+
return {getImpl().LoadedModules.begin(), getImpl().LoadedModules.end()};
1549+
}
1550+
15411551
ModuleDecl *ASTContext::getLoadedModule(Identifier ModuleName) const {
1542-
return LoadedModules.lookup(ModuleName);
1552+
return getImpl().LoadedModules.lookup(ModuleName);
1553+
}
1554+
1555+
void ASTContext::addLoadedModule(ModuleDecl *M) {
1556+
assert(M);
1557+
getImpl().LoadedModules[M->getName()] = M;
15431558
}
15441559

15451560
static AllocationArena getArena(GenericSignature genericSig) {

lib/ClangImporter/ClangImporter.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,9 +1825,9 @@ ModuleDecl *ClangImporter::Implementation::finishLoadingClangModule(
18251825
if (clangModule->isSubModule()) {
18261826
finishLoadingClangModule(clangModule->getTopLevelModule(), importLoc);
18271827
} else {
1828-
ModuleDecl *&loaded = SwiftContext.LoadedModules[result->getName()];
1829-
if (!loaded)
1830-
loaded = result;
1828+
1829+
if (!SwiftContext.getLoadedModule(result->getName()))
1830+
SwiftContext.addLoadedModule(result);
18311831
}
18321832

18331833
return result;
@@ -3368,10 +3368,12 @@ ModuleDecl *ClangModuleUnit::getOverlayModule() const {
33683368
if (overlay == M) {
33693369
overlay = nullptr;
33703370
} else {
3371-
auto &sharedModuleRef = Ctx.LoadedModules[M->getName()];
3371+
// FIXME: This bizarre and twisty invariant is due to nested
3372+
// re-entrancy in both clang module loading and overlay module loading.
3373+
auto *sharedModuleRef = Ctx.getLoadedModule(M->getName());
33723374
assert(!sharedModuleRef || sharedModuleRef == overlay ||
33733375
sharedModuleRef == M);
3374-
sharedModuleRef = overlay;
3376+
Ctx.addLoadedModule(overlay);
33753377
}
33763378

33773379
auto mutableThis = const_cast<ClangModuleUnit *>(this);

lib/ClangImporter/DWARFImporter.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,8 @@ ModuleDecl *ClangImporter::Implementation::loadModuleDWARF(
121121
(void) namelookup::getAllImports(decl);
122122

123123
// Register the module with the ASTContext so it is available for lookups.
124-
ModuleDecl *&loaded = SwiftContext.LoadedModules[name];
125-
if (!loaded)
126-
loaded = decl;
124+
if (!SwiftContext.getLoadedModule(name))
125+
SwiftContext.addLoadedModule(decl);
127126

128127
return decl;
129128
}

lib/Frontend/Frontend.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,8 @@ ModuleDecl *CompilerInstance::getMainModule() const {
751751
if (Invocation.getFrontendOptions().EnableLibraryEvolution)
752752
MainModule->setResilienceStrategy(ResilienceStrategy::Resilient);
753753

754-
Context->LoadedModules[MainModule->getName()] = MainModule;
754+
// Register the main module with the AST context.
755+
Context->addLoadedModule(MainModule);
755756

756757
// Create and add the module's files.
757758
SmallVector<FileUnit *, 16> files;
@@ -773,7 +774,7 @@ ModuleDecl *CompilerInstance::getMainModule() const {
773774
void CompilerInstance::setMainModule(ModuleDecl *newMod) {
774775
assert(newMod->isMainModule());
775776
MainModule = newMod;
776-
Context->LoadedModules[newMod->getName()] = newMod;
777+
Context->addLoadedModule(newMod);
777778
}
778779

779780
void CompilerInstance::performParseAndResolveImportsOnly() {

lib/FrontendTool/FrontendTool.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ static bool emitLoadedModuleTraceIfNeeded(ModuleDecl *mainModule,
436436
importedModules.insert(import.importedModule);
437437

438438
llvm::DenseMap<StringRef, ModuleDecl *> pathToModuleDecl;
439-
for (auto &module : ctxt.LoadedModules) {
439+
for (const auto &module : ctxt.getLoadedModules()) {
440440
ModuleDecl *loadedDecl = module.second;
441441
if (!loadedDecl)
442442
llvm::report_fatal_error("Expected loaded modules to be non-null.");
@@ -690,7 +690,7 @@ static void countStatsPostSema(UnifiedStatsReporter &Stats,
690690
C.NumLinkLibraries = Instance.getLinkLibraries().size();
691691

692692
auto const &AST = Instance.getASTContext();
693-
C.NumLoadedModules = AST.LoadedModules.size();
693+
C.NumLoadedModules = AST.getNumLoadedModules();
694694

695695
if (auto *D = Instance.getDependencyTracker()) {
696696
C.NumDependencies = D->getDependencies().size();
@@ -1229,9 +1229,9 @@ static void performEndOfPipelineActions(CompilerInstance &Instance) {
12291229
auto action = Instance.getInvocation().getFrontendOptions().RequestedAction;
12301230
if (FrontendOptions::shouldActionOnlyParse(action) &&
12311231
action != FrontendOptions::ActionType::EmitImportedModules) {
1232-
assert(ctx.LoadedModules.size() == 1 &&
1232+
assert(ctx.getNumLoadedModules() == 1 &&
12331233
"Loaded a module during parse-only");
1234-
assert(ctx.LoadedModules.front().second == Instance.getMainModule());
1234+
assert(ctx.getLoadedModules().begin()->second == Instance.getMainModule());
12351235
}
12361236

12371237
// Verify the AST for all the modules we've loaded.

lib/Sema/SourceLoader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ ModuleDecl *SourceLoader::loadModule(SourceLoc importLoc,
118118
auto *importMod = ModuleDecl::create(moduleID.Item, Ctx, importInfo);
119119
if (EnableLibraryEvolution)
120120
importMod->setResilienceStrategy(ResilienceStrategy::Resilient);
121-
Ctx.LoadedModules[moduleID.Item] = importMod;
121+
Ctx.addLoadedModule(importMod);
122122

123123
auto *importFile =
124124
new (Ctx) SourceFile(*importMod, SourceFileKind::Library, bufferID,

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,7 @@ SerializedModuleLoaderBase::loadModule(SourceLoc importLoc,
959959

960960
auto M = ModuleDecl::create(moduleID.Item, Ctx);
961961
M->setIsSystemModule(isSystemModule);
962-
Ctx.LoadedModules[moduleID.Item] = M;
962+
Ctx.addLoadedModule(M);
963963
SWIFT_DEFER { M->setHasResolvedImports(); };
964964

965965
StringRef moduleInterfacePathStr =
@@ -1010,7 +1010,7 @@ MemoryBufferSerializedModuleLoader::loadModule(SourceLoc importLoc,
10101010
return nullptr;
10111011

10121012
M->addFile(*file);
1013-
Ctx.LoadedModules[moduleID.Item] = M;
1013+
Ctx.addLoadedModule(M);
10141014
return M;
10151015
}
10161016

lib/Serialization/SerializedSILLoader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ SerializedSILLoader::SerializedSILLoader(
2727

2828
// Get a list of SerializedModules from ASTContext.
2929
// FIXME: Iterating over LoadedModules is not a good way to do this.
30-
for (auto &Entry : Ctx.LoadedModules) {
30+
for (const auto &Entry : Ctx.getLoadedModules()) {
3131
for (auto File : Entry.second->getFiles()) {
3232
if (auto LoadedAST = dyn_cast<SerializedASTFile>(File)) {
3333
auto Des = new SILDeserializer(&LoadedAST->File, *SILMod, callbacks);

unittests/AST/TestContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ TestContext::TestContext(ShouldDeclareOptionalTypes optionals)
4040
registerTypeCheckerRequestFunctions(Ctx.evaluator);
4141
auto stdlibID = Ctx.getIdentifier(STDLIB_NAME);
4242
auto *module = ModuleDecl::create(stdlibID, Ctx);
43-
Ctx.LoadedModules[stdlibID] = module;
43+
Ctx.addLoadedModule(module);
4444

4545
FileForLookups = new (Ctx) SourceFile(*module, SourceFileKind::Library,
4646
/*buffer*/ None);

0 commit comments

Comments
 (0)