Skip to content

Commit a71e4fb

Browse files
authored
Merge pull request swiftlang#34121 from nkcsgexi/refactor-module-interface-loader
ModuleInterface: refactor ModuleInterfaceChecker out of ModuleInterfaceLoader
2 parents ded29c5 + 8ccee27 commit a71e4fb

File tree

10 files changed

+117
-91
lines changed

10 files changed

+117
-91
lines changed

include/swift/AST/ASTContext.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,12 @@ class ASTContext final {
762762
bool isClang = false, bool isDWARF = false,
763763
bool IsInterface = false);
764764

765+
/// Add a module interface checker to use for this AST context.
766+
void addModuleInterfaceChecker(std::unique_ptr<ModuleInterfaceChecker> checker);
767+
768+
/// Retrieve the module interface checker associated with this AST context.
769+
ModuleInterfaceChecker *getModuleInterfaceChecker() const;
770+
765771
/// Retrieve the module dependencies for the module with the given name.
766772
///
767773
/// \param isUnderlyingClangModule When true, only look for a Clang module
@@ -839,9 +845,6 @@ class ASTContext final {
839845
/// If there is no Clang module loader, returns a null pointer.
840846
/// The loader is owned by the AST context.
841847
ClangModuleLoader *getDWARFModuleLoader() const;
842-
843-
/// Retrieve the module interface loader for this ASTContext.
844-
ModuleLoader *getModuleInterfaceLoader() const;
845848
public:
846849
namelookup::ImportCache &getImportCache() const;
847850

include/swift/AST/ModuleLoader.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,23 @@ struct SubCompilerInstanceInfo {
116116
ArrayRef<StringRef> ExtraPCMArgs;
117117
};
118118

119+
/// Abstract interface for a checker of module interfaces and prebuilt modules.
120+
class ModuleInterfaceChecker {
121+
public:
122+
virtual std::vector<std::string>
123+
getCompiledModuleCandidatesForInterface(StringRef moduleName,
124+
StringRef interfacePath) = 0;
125+
126+
/// Given a list of potential ready-to-use compiled modules for \p interfacePath,
127+
/// check if any one of them is up-to-date. If so, emit a forwarding module
128+
/// to the candidate binary module to \p outPath.
129+
virtual bool tryEmitForwardingModule(StringRef moduleName,
130+
StringRef interfacePath,
131+
ArrayRef<std::string> candidates,
132+
StringRef outPath) = 0;
133+
virtual ~ModuleInterfaceChecker() = default;
134+
};
135+
119136
/// Abstract interface to run an action in a sub ASTContext.
120137
struct InterfaceSubContextDelegate {
121138
virtual std::error_code runInSubContext(StringRef moduleName,

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -309,27 +309,52 @@ struct ModuleInterfaceLoaderOptions {
309309
ModuleInterfaceLoaderOptions() = default;
310310
};
311311

312+
class ModuleInterfaceCheckerImpl: public ModuleInterfaceChecker {
313+
friend class ModuleInterfaceLoader;
314+
ASTContext &Ctx;
315+
std::string CacheDir;
316+
std::string PrebuiltCacheDir;
317+
ModuleInterfaceLoaderOptions Opts;
318+
319+
public:
320+
explicit ModuleInterfaceCheckerImpl(ASTContext &Ctx,
321+
StringRef cacheDir,
322+
StringRef prebuiltCacheDir,
323+
ModuleInterfaceLoaderOptions Opts)
324+
: Ctx(Ctx), CacheDir(cacheDir), PrebuiltCacheDir(prebuiltCacheDir),
325+
Opts(Opts) {}
326+
327+
std::vector<std::string>
328+
getCompiledModuleCandidatesForInterface(StringRef moduleName,
329+
StringRef interfacePath) override;
330+
331+
/// Given a list of potential ready-to-use compiled modules for \p interfacePath,
332+
/// check if any one of them is up-to-date. If so, emit a forwarding module
333+
/// to the candidate binary module to \p outPath.
334+
bool tryEmitForwardingModule(StringRef moduleName,
335+
StringRef interfacePath,
336+
ArrayRef<std::string> candidates,
337+
StringRef outPath) override;
338+
bool isCached(StringRef DepPath);
339+
};
340+
312341
/// A ModuleLoader that runs a subordinate \c CompilerInvocation and
313342
/// \c CompilerInstance to convert .swiftinterface files to .swiftmodule
314343
/// files on the fly, caching the resulting .swiftmodules in the module cache
315344
/// directory, and loading the serialized .swiftmodules from there.
316345
class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
317346
friend class unittest::ModuleInterfaceLoaderTest;
318347
explicit ModuleInterfaceLoader(
319-
ASTContext &ctx, StringRef cacheDir, StringRef prebuiltCacheDir,
348+
ASTContext &ctx, ModuleInterfaceCheckerImpl &InterfaceChecker,
320349
DependencyTracker *tracker, ModuleLoadingMode loadMode,
321350
ArrayRef<std::string> PreferInterfaceForModules,
322-
bool IgnoreSwiftSourceInfoFile, ModuleInterfaceLoaderOptions Opts)
323-
: SerializedModuleLoaderBase(ctx, tracker, loadMode,
324-
IgnoreSwiftSourceInfoFile),
325-
CacheDir(cacheDir), PrebuiltCacheDir(prebuiltCacheDir),
326-
PreferInterfaceForModules(PreferInterfaceForModules),
327-
Opts(Opts) {}
351+
bool IgnoreSwiftSourceInfoFile)
352+
: SerializedModuleLoaderBase(ctx, tracker, loadMode, IgnoreSwiftSourceInfoFile),
353+
InterfaceChecker(InterfaceChecker),
354+
PreferInterfaceForModules(PreferInterfaceForModules){}
328355

329-
std::string CacheDir;
330-
std::string PrebuiltCacheDir;
356+
ModuleInterfaceCheckerImpl &InterfaceChecker;
331357
ArrayRef<std::string> PreferInterfaceForModules;
332-
ModuleInterfaceLoaderOptions Opts;
333358

334359
std::error_code findModuleFilesInDirectory(
335360
ImportPath::Element ModuleID,
@@ -343,17 +368,14 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
343368
bool isCached(StringRef DepPath) override;
344369
public:
345370
static std::unique_ptr<ModuleInterfaceLoader>
346-
create(ASTContext &ctx, StringRef cacheDir, StringRef prebuiltCacheDir,
371+
create(ASTContext &ctx, ModuleInterfaceCheckerImpl &InterfaceChecker,
347372
DependencyTracker *tracker, ModuleLoadingMode loadMode,
348373
ArrayRef<std::string> PreferInterfaceForModules = {},
349-
ModuleInterfaceLoaderOptions Opts = ModuleInterfaceLoaderOptions(),
350374
bool IgnoreSwiftSourceInfoFile = false) {
351375
return std::unique_ptr<ModuleInterfaceLoader>(
352-
new ModuleInterfaceLoader(ctx, cacheDir, prebuiltCacheDir,
353-
tracker, loadMode,
354-
PreferInterfaceForModules,
355-
IgnoreSwiftSourceInfoFile,
356-
Opts));
376+
new ModuleInterfaceLoader(ctx, InterfaceChecker, tracker, loadMode,
377+
PreferInterfaceForModules,
378+
IgnoreSwiftSourceInfoFile));
357379
}
358380

359381
/// Append visible module names to \p names. Note that names are possibly
@@ -373,18 +395,6 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
373395
StringRef ModuleName, StringRef InPath, StringRef OutPath,
374396
bool SerializeDependencyHashes, bool TrackSystemDependencies,
375397
ModuleInterfaceLoaderOptions Opts);
376-
377-
std::vector<std::string>
378-
getCompiledModuleCandidatesForInterface(StringRef moduleName,
379-
StringRef interfacePath) override;
380-
381-
/// Given a list of potential ready-to-use compiled modules for \p interfacePath,
382-
/// check if any one of them is up-to-date. If so, emit a forwarding module
383-
/// to the candidate binary module to \p outPath.
384-
bool tryEmitForwardingModule(StringRef moduleName,
385-
StringRef interfacePath,
386-
ArrayRef<std::string> candidates,
387-
StringRef outPath) override;
388398
};
389399

390400
struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -201,18 +201,6 @@ class SerializedModuleLoaderBase : public ModuleLoader {
201201
virtual Optional<ModuleDependencies> getModuleDependencies(
202202
StringRef moduleName, ModuleDependenciesCache &cache,
203203
InterfaceSubContextDelegate &delegate) override;
204-
205-
virtual std::vector<std::string>
206-
getCompiledModuleCandidatesForInterface(StringRef moduleName,
207-
StringRef interfacePath) {
208-
return std::vector<std::string>();
209-
}
210-
virtual bool tryEmitForwardingModule(StringRef moduleName,
211-
StringRef interfacePath,
212-
ArrayRef<std::string> candidates,
213-
StringRef outPath) {
214-
return false;
215-
}
216204
};
217205

218206
/// Imports serialized Swift modules into an ASTContext.

lib/AST/ASTContext.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,9 @@ struct ASTContext::Implementation {
255255
/// The set of known protocols, lazily populated as needed.
256256
ProtocolDecl *KnownProtocols[NumKnownProtocols] = { };
257257

258+
/// The module interface checker owned by the ASTContext.
259+
std::unique_ptr<ModuleInterfaceChecker> InterfaceChecker;
260+
258261
/// The various module loaders that import external modules into this
259262
/// ASTContext.
260263
SmallVector<std::unique_ptr<swift::ModuleLoader>, 4> ModuleLoaders;
@@ -268,9 +271,6 @@ struct ASTContext::Implementation {
268271
/// The module loader used to load Clang modules from DWARF.
269272
ClangModuleLoader *TheDWARFModuleLoader = nullptr;
270273

271-
/// The module loader used to load Swift textual interface.
272-
ModuleLoader *TheModuleInterfaceLoader = nullptr;
273-
274274
/// Map from Swift declarations to raw comments.
275275
llvm::DenseMap<const Decl *, RawComment> RawComments;
276276

@@ -1522,11 +1522,15 @@ void ASTContext::addModuleLoader(std::unique_ptr<ModuleLoader> loader,
15221522
if (IsClang && IsDwarf && !getImpl().TheDWARFModuleLoader)
15231523
getImpl().TheDWARFModuleLoader =
15241524
static_cast<ClangModuleLoader *>(loader.get());
1525-
if (IsInterface && !getImpl().TheModuleInterfaceLoader)
1526-
getImpl().TheModuleInterfaceLoader = loader.get();
15271525
getImpl().ModuleLoaders.push_back(std::move(loader));
15281526
}
15291527

1528+
void ASTContext::addModuleInterfaceChecker(
1529+
std::unique_ptr<ModuleInterfaceChecker> checker) {
1530+
assert(!getImpl().InterfaceChecker && "Checker has been set already");
1531+
getImpl().InterfaceChecker = std::move(checker);
1532+
}
1533+
15301534
Optional<ModuleDependencies> ASTContext::getModuleDependencies(
15311535
StringRef moduleName, bool isUnderlyingClangModule,
15321536
ModuleDependenciesCache &cache, InterfaceSubContextDelegate &delegate) {
@@ -1613,8 +1617,10 @@ ClangModuleLoader *ASTContext::getDWARFModuleLoader() const {
16131617
return getImpl().TheDWARFModuleLoader;
16141618
}
16151619

1616-
ModuleLoader *ASTContext::getModuleInterfaceLoader() const {
1617-
return getImpl().TheModuleInterfaceLoader;
1620+
ModuleInterfaceChecker *ASTContext::getModuleInterfaceChecker() const {
1621+
auto *result = getImpl().InterfaceChecker.get();
1622+
assert(result);
1623+
return result;
16181624
}
16191625

16201626
ModuleDecl *ASTContext::getLoadedModule(

lib/Frontend/Frontend.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,14 @@ bool CompilerInstance::setUpModuleLoaders() {
493493
return true;
494494
}
495495

496+
// Configure ModuleInterfaceChecker for the ASTContext.
497+
auto const &Clang = clangImporter->getClangInstance();
498+
std::string ModuleCachePath = getModuleCachePathFromClang(Clang);
499+
auto &FEOpts = Invocation.getFrontendOptions();
500+
ModuleInterfaceLoaderOptions LoaderOpts(FEOpts);
501+
Context->addModuleInterfaceChecker(
502+
std::make_unique<ModuleInterfaceCheckerImpl>(*Context, ModuleCachePath,
503+
FEOpts.PrebuiltModuleCachePath, LoaderOpts));
496504
// If implicit modules are disabled, we need to install an explicit module
497505
// loader.
498506
bool ExplicitModuleBuild = Invocation.getFrontendOptions().DisableImplicitModules;
@@ -505,23 +513,15 @@ bool CompilerInstance::setUpModuleLoaders() {
505513
IgnoreSourceInfoFile);
506514
this->DefaultSerializedLoader = ESML.get();
507515
Context->addModuleLoader(std::move(ESML));
508-
}
509-
510-
if (MLM != ModuleLoadingMode::OnlySerialized) {
511-
auto const &Clang = clangImporter->getClangInstance();
512-
std::string ModuleCachePath = getModuleCachePathFromClang(Clang);
513-
auto &FEOpts = Invocation.getFrontendOptions();
514-
StringRef PrebuiltModuleCachePath = FEOpts.PrebuiltModuleCachePath;
515-
ModuleInterfaceLoaderOptions LoaderOpts(FEOpts);
516-
auto PIML = ModuleInterfaceLoader::create(
517-
*Context, ModuleCachePath, PrebuiltModuleCachePath,
518-
getDependencyTracker(), MLM, FEOpts.PreferInterfaceForModules,
519-
LoaderOpts,
520-
IgnoreSourceInfoFile);
521-
Context->addModuleLoader(std::move(PIML), false, false, true);
522-
}
523-
524-
if (!ExplicitModuleBuild) {
516+
} else {
517+
if (MLM != ModuleLoadingMode::OnlySerialized) {
518+
// We only need ModuleInterfaceLoader for implicit modules.
519+
auto PIML = ModuleInterfaceLoader::create(
520+
*Context, *static_cast<ModuleInterfaceCheckerImpl*>(Context
521+
->getModuleInterfaceChecker()), getDependencyTracker(), MLM,
522+
FEOpts.PreferInterfaceForModules, IgnoreSourceInfoFile);
523+
Context->addModuleLoader(std::move(PIML), false, false, true);
524+
}
525525
std::unique_ptr<ImplicitSerializedModuleLoader> ISML =
526526
ImplicitSerializedModuleLoader::create(*Context, getDependencyTracker(), MLM,
527527
IgnoreSourceInfoFile);

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,9 @@ bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
170170
auto &SubInstance = *info.Instance;
171171
auto subInvocation = SubInstance.getInvocation();
172172
// Try building forwarding module first. If succeed, return.
173-
if (static_cast<ModuleInterfaceLoader*>(SubInstance.getASTContext()
174-
.getModuleInterfaceLoader())->tryEmitForwardingModule(moduleName,
175-
interfacePath,
176-
CompiledCandidates, OutPath)) {
173+
if (SubInstance.getASTContext().getModuleInterfaceChecker()
174+
->tryEmitForwardingModule(moduleName, interfacePath,
175+
CompiledCandidates, OutPath)) {
177176
return std::error_code();
178177
}
179178
FrontendOptions &FEOpts = subInvocation.getFrontendOptions();

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ struct ModuleRebuildInfo {
335335
/// a module that we'll build from a module interface.
336336
class ModuleInterfaceLoaderImpl {
337337
friend class swift::ModuleInterfaceLoader;
338+
friend class swift::ModuleInterfaceCheckerImpl;
338339
ASTContext &ctx;
339340
llvm::vfs::FileSystem &fs;
340341
DiagnosticEngine &diags;
@@ -907,10 +908,6 @@ class ModuleInterfaceLoaderImpl {
907908

908909
return std::move(module.moduleBuffer);
909910
}
910-
// If implicit module is disabled, we are done.
911-
if (Opts.disableImplicitSwiftModule) {
912-
return std::make_error_code(std::errc::not_supported);
913-
}
914911

915912
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
916913

@@ -942,12 +939,16 @@ class ModuleInterfaceLoaderImpl {
942939

943940
} // end anonymous namespace
944941

945-
bool ModuleInterfaceLoader::isCached(StringRef DepPath) {
942+
bool ModuleInterfaceCheckerImpl::isCached(StringRef DepPath) {
946943
if (!CacheDir.empty() && DepPath.startswith(CacheDir))
947944
return true;
948945
return !PrebuiltCacheDir.empty() && DepPath.startswith(PrebuiltCacheDir);
949946
}
950947

948+
bool ModuleInterfaceLoader::isCached(StringRef DepPath) {
949+
return InterfaceChecker.isCached(DepPath);
950+
}
951+
951952
/// Load a .swiftmodule associated with a .swiftinterface either from a
952953
/// cache or by converting it in a subordinate \c CompilerInstance, caching
953954
/// the results.
@@ -990,8 +991,8 @@ std::error_code ModuleInterfaceLoader::findModuleFilesInDirectory(
990991
auto ModuleName = ModuleID.Item.str();
991992
ModuleInterfaceLoaderImpl Impl(
992993
Ctx, ModPath, InPath, ModuleName,
993-
CacheDir, PrebuiltCacheDir, ModuleID.Loc,
994-
Opts,
994+
InterfaceChecker.CacheDir, InterfaceChecker.PrebuiltCacheDir,
995+
ModuleID.Loc, InterfaceChecker.Opts,
995996
dependencyTracker,
996997
llvm::is_contained(PreferInterfaceForModules,
997998
ModuleName) ?
@@ -1024,8 +1025,8 @@ std::error_code ModuleInterfaceLoader::findModuleFilesInDirectory(
10241025
}
10251026

10261027
std::vector<std::string>
1027-
ModuleInterfaceLoader::getCompiledModuleCandidatesForInterface(StringRef moduleName,
1028-
StringRef interfacePath) {
1028+
ModuleInterfaceCheckerImpl::getCompiledModuleCandidatesForInterface(
1029+
StringRef moduleName, StringRef interfacePath) {
10291030
// Derive .swiftmodule path from the .swiftinterface path.
10301031
auto newExt = file_types::getExtension(file_types::TY_SwiftModuleFile);
10311032
llvm::SmallString<32> modulePath = interfacePath;
@@ -1034,9 +1035,8 @@ ModuleInterfaceLoader::getCompiledModuleCandidatesForInterface(StringRef moduleN
10341035
Ctx, modulePath, interfacePath, moduleName,
10351036
CacheDir, PrebuiltCacheDir, SourceLoc(),
10361037
Opts,
1037-
dependencyTracker,
1038-
llvm::is_contained(PreferInterfaceForModules, moduleName) ?
1039-
ModuleLoadingMode::PreferInterface : LoadMode);
1038+
nullptr,
1039+
ModuleLoadingMode::PreferSerialized);
10401040
std::vector<std::string> results;
10411041
auto pair = Impl.getCompiledModuleCandidates();
10421042
// Add compiled module candidates only when they are non-empty.
@@ -1047,7 +1047,7 @@ ModuleInterfaceLoader::getCompiledModuleCandidatesForInterface(StringRef moduleN
10471047
return results;
10481048
}
10491049

1050-
bool ModuleInterfaceLoader::tryEmitForwardingModule(StringRef moduleName,
1050+
bool ModuleInterfaceCheckerImpl::tryEmitForwardingModule(StringRef moduleName,
10511051
StringRef interfacePath,
10521052
ArrayRef<std::string> candidates,
10531053
StringRef outputPath) {
@@ -1059,9 +1059,8 @@ bool ModuleInterfaceLoader::tryEmitForwardingModule(StringRef moduleName,
10591059
Ctx, modulePath, interfacePath, moduleName,
10601060
CacheDir, PrebuiltCacheDir, SourceLoc(),
10611061
Opts,
1062-
dependencyTracker,
1063-
llvm::is_contained(PreferInterfaceForModules, moduleName) ?
1064-
ModuleLoadingMode::PreferInterface : LoadMode);
1062+
nullptr,
1063+
ModuleLoadingMode::PreferSerialized);
10651064
SmallVector<FileDependency, 16> deps;
10661065
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
10671066
for (auto mod: candidates) {

lib/Serialization/ModuleDependencyScanner.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,7 @@ std::error_code PlaceholderSwiftModuleScanner::findModuleFilesInDirectory(
9898
static std::vector<std::string> getCompiledCandidates(ASTContext &ctx,
9999
StringRef moduleName,
100100
StringRef interfacePath) {
101-
return static_cast<SerializedModuleLoaderBase*>(ctx
102-
.getModuleInterfaceLoader())->getCompiledModuleCandidatesForInterface(
101+
return ctx.getModuleInterfaceChecker()->getCompiledModuleCandidatesForInterface(
103102
moduleName.str(), interfacePath);
104103
}
105104

unittests/FrontendTool/ModuleLoadingTests.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,13 @@ class ModuleInterfaceLoaderTest : public testing::Test {
103103
ASTContext::get(langOpts, typeckOpts, searchPathOpts, clangImpOpts,
104104
sourceMgr, diags);
105105

106+
ctx->addModuleInterfaceChecker(
107+
std::make_unique<ModuleInterfaceCheckerImpl>(*ctx, cacheDir,
108+
prebuiltCacheDir, ModuleInterfaceLoaderOptions()));
109+
106110
auto loader = ModuleInterfaceLoader::create(
107-
*ctx, cacheDir, prebuiltCacheDir,
111+
*ctx, *static_cast<ModuleInterfaceCheckerImpl*>(
112+
ctx->getModuleInterfaceChecker()),
108113
/*dependencyTracker*/nullptr,
109114
ModuleLoadingMode::PreferSerialized);
110115

0 commit comments

Comments
 (0)