Skip to content

Commit 42a89af

Browse files
authored
Merge pull request #37355 from nkcsgexi/77676064-flag
Frontend: teach the compiler to use a backup directory to find .swiftinterface files to compile
2 parents eb945c8 + b6cd513 commit 42a89af

20 files changed

+304
-75
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,8 @@ ERROR(error_option_required,none, "option '%0' is required", (StringRef))
405405
ERROR(error_nonexistent_output_dir,none,
406406
"'-output-dir' argument '%0' does not exist or is not a directory", (StringRef))
407407

408+
REMARK(interface_file_backup_used,none,
409+
"building module from '%0' failed; retrying building module from '%1'", (StringRef, StringRef))
408410

409411
// Dependency Verifier Diagnostics
410412
ERROR(missing_member_dependency,none,

include/swift/AST/ModuleLoader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ class ModuleInterfaceChecker {
157157
ArrayRef<std::string> candidates,
158158
StringRef outPath) = 0;
159159
virtual ~ModuleInterfaceChecker() = default;
160+
virtual std::string getBackupPublicModuleInterfacePath(StringRef moduleName,
161+
StringRef interfacePath) = 0;
160162
};
161163

162164
/// Abstract interface to run an action in a sub ASTContext.

include/swift/Frontend/FrontendOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ class FrontendOptions {
8181
/// binary module has already been built for use by the compiler.
8282
std::string PrebuiltModuleCachePath;
8383

84+
/// The path to look in to find backup .swiftinterface files if those found
85+
/// from SDKs are failing.
86+
std::string BackupModuleInterfaceDir;
87+
8488
/// For these modules, we should prefer using Swift interface when importing them.
8589
std::vector<std::string> PreferInterfaceForModules;
8690

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -336,17 +336,25 @@ class ModuleInterfaceCheckerImpl: public ModuleInterfaceChecker {
336336
ASTContext &Ctx;
337337
std::string CacheDir;
338338
std::string PrebuiltCacheDir;
339+
std::string BackupInterfaceDir;
339340
ModuleInterfaceLoaderOptions Opts;
340341
RequireOSSAModules_t RequiresOSSAModules;
341342

342343
public:
343344
explicit ModuleInterfaceCheckerImpl(ASTContext &Ctx, StringRef cacheDir,
344345
StringRef prebuiltCacheDir,
346+
StringRef BackupInterfaceDir,
345347
ModuleInterfaceLoaderOptions opts,
346348
RequireOSSAModules_t requiresOSSAModules)
347349
: Ctx(Ctx), CacheDir(cacheDir), PrebuiltCacheDir(prebuiltCacheDir),
350+
BackupInterfaceDir(BackupInterfaceDir),
348351
Opts(opts), RequiresOSSAModules(requiresOSSAModules) {}
349-
352+
explicit ModuleInterfaceCheckerImpl(ASTContext &Ctx, StringRef cacheDir,
353+
StringRef prebuiltCacheDir,
354+
ModuleInterfaceLoaderOptions opts,
355+
RequireOSSAModules_t requiresOSSAModules):
356+
ModuleInterfaceCheckerImpl(Ctx, cacheDir, prebuiltCacheDir, StringRef(),
357+
opts, requiresOSSAModules) {}
350358
std::vector<std::string>
351359
getCompiledModuleCandidatesForInterface(StringRef moduleName,
352360
StringRef interfacePath) override;
@@ -359,6 +367,8 @@ class ModuleInterfaceCheckerImpl: public ModuleInterfaceChecker {
359367
ArrayRef<std::string> candidates,
360368
StringRef outPath) override;
361369
bool isCached(StringRef DepPath);
370+
std::string getBackupPublicModuleInterfacePath(StringRef moduleName,
371+
StringRef interfacePath) override;
362372
};
363373

364374
/// A ModuleLoader that runs a subordinate \c CompilerInvocation and
@@ -414,7 +424,8 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
414424
SourceManager &SourceMgr, DiagnosticEngine &Diags,
415425
const SearchPathOptions &SearchPathOpts, const LangOptions &LangOpts,
416426
const ClangImporterOptions &ClangOpts, StringRef CacheDir,
417-
StringRef PrebuiltCacheDir, StringRef ModuleName, StringRef InPath,
427+
StringRef PrebuiltCacheDir, StringRef BackupInterfaceDir,
428+
StringRef ModuleName, StringRef InPath,
418429
StringRef OutPath, bool SerializeDependencyHashes,
419430
bool TrackSystemDependencies, ModuleInterfaceLoaderOptions Opts,
420431
RequireOSSAModules_t RequireOSSAModules);
@@ -423,7 +434,9 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
423434
struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
424435
private:
425436
SourceManager &SM;
426-
DiagnosticEngine &Diags;
437+
public:
438+
DiagnosticEngine *Diags;
439+
private:
427440
llvm::BumpPtrAllocator Allocator;
428441
llvm::StringSaver ArgSaver;
429442
std::vector<StringRef> GenericArgs;
@@ -439,7 +452,7 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
439452
// Diagnose this inside the interface file, if possible.
440453
loc = SM.getLocFromExternalSource(interfacePath, 1, 1);
441454
}
442-
return Diags.diagnose(loc, ID, std::move(Args)...);
455+
return Diags->diagnose(loc, ID, std::move(Args)...);
443456
}
444457
void
445458
inheritOptionsForBuildingInterface(const SearchPathOptions &SearchPathOpts,
@@ -452,11 +465,12 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
452465
SourceLoc diagnosticLoc);
453466
public:
454467
InterfaceSubContextDelegateImpl(
455-
SourceManager &SM, DiagnosticEngine &Diags,
468+
SourceManager &SM, DiagnosticEngine *Diags,
456469
const SearchPathOptions &searchPathOpts, const LangOptions &langOpts,
457470
const ClangImporterOptions &clangImporterOpts,
458471
ModuleInterfaceLoaderOptions LoaderOpts, bool buildModuleCacheDirIfAbsent,
459472
StringRef moduleCachePath, StringRef prebuiltCachePath,
473+
StringRef backupModuleInterfaceDir,
460474
bool serializeDependencyHashes, bool trackSystemDependencies,
461475
RequireOSSAModules_t requireOSSAModules);
462476
std::error_code runInSubContext(StringRef moduleName,

include/swift/Option/FrontendOptions.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,13 @@ def prebuilt_module_cache_path_EQ :
695695
Joined<["-"], "prebuilt-module-cache-path=">,
696696
Alias<prebuilt_module_cache_path>;
697697

698+
def backup_module_interface_path :
699+
Separate<["-"], "backup-module-interface-path">,
700+
HelpText<"Directory of module interfaces as backups to those from SDKs">;
701+
def backup_module_interface_path_EQ :
702+
Joined<["-"], "backup-module-interface-path=">,
703+
Alias<backup_module_interface_path>;
704+
698705
def force_public_linkage : Flag<["-"], "force-public-linkage">,
699706
HelpText<"Force public linkage for private symbols. Used by LLDB.">;
700707

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,9 @@ class SerializedASTFile final : public LoadedFile {
471471
/// Extract compiler arguments from an interface file buffer.
472472
bool extractCompilerFlagsFromInterface(StringRef buffer, llvm::StringSaver &ArgSaver,
473473
SmallVectorImpl<const char *> &SubArgs);
474+
475+
/// Extract the user module version number from an interface file.
476+
llvm::VersionTuple extractUserModuleVersionFromInterface(StringRef moduleInterfacePath);
474477
} // end namespace swift
475478

476479
#endif

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,10 +1240,11 @@ swift::dependencies::performModuleScan(CompilerInstance &instance,
12401240
auto &FEOpts = instance.getInvocation().getFrontendOptions();
12411241
ModuleInterfaceLoaderOptions LoaderOpts(FEOpts);
12421242
InterfaceSubContextDelegateImpl ASTDelegate(
1243-
ctx.SourceMgr, ctx.Diags, ctx.SearchPathOpts, ctx.LangOpts,
1243+
ctx.SourceMgr, &ctx.Diags, ctx.SearchPathOpts, ctx.LangOpts,
12441244
ctx.ClangImporterOpts, LoaderOpts,
12451245
/*buildModuleCacheDirIfAbsent*/ false, ModuleCachePath,
12461246
FEOpts.PrebuiltModuleCachePath,
1247+
FEOpts.BackupModuleInterfaceDir,
12471248
FEOpts.SerializeModuleInterfaceDependencyHashes,
12481249
FEOpts.shouldTrackSystemDependencies(),
12491250
RequireOSSAModules_t(instance.getSILOptions()));
@@ -1332,10 +1333,11 @@ swift::dependencies::performBatchModuleScan(
13321333
std::set<ModuleDependencyID>>
13331334
allModules;
13341335
InterfaceSubContextDelegateImpl ASTDelegate(
1335-
ctx.SourceMgr, ctx.Diags, ctx.SearchPathOpts, ctx.LangOpts,
1336+
ctx.SourceMgr, &ctx.Diags, ctx.SearchPathOpts, ctx.LangOpts,
13361337
ctx.ClangImporterOpts, LoaderOpts,
13371338
/*buildModuleCacheDirIfAbsent*/ false, ModuleCachePath,
13381339
FEOpts.PrebuiltModuleCachePath,
1340+
FEOpts.BackupModuleInterfaceDir,
13391341
FEOpts.SerializeModuleInterfaceDependencyHashes,
13401342
FEOpts.shouldTrackSystemDependencies(),
13411343
RequireOSSAModules_t(instance.getSILOptions()));
@@ -1400,10 +1402,11 @@ swift::dependencies::performBatchModulePrescan(
14001402
std::set<ModuleDependencyID>>
14011403
allModules;
14021404
InterfaceSubContextDelegateImpl ASTDelegate(
1403-
ctx.SourceMgr, ctx.Diags, ctx.SearchPathOpts, ctx.LangOpts,
1405+
ctx.SourceMgr, &ctx.Diags, ctx.SearchPathOpts, ctx.LangOpts,
14041406
ctx.ClangImporterOpts, LoaderOpts,
14051407
/*buildModuleCacheDirIfAbsent*/ false, ModuleCachePath,
14061408
FEOpts.PrebuiltModuleCachePath,
1409+
FEOpts.BackupModuleInterfaceDir,
14071410
FEOpts.SerializeModuleInterfaceDependencyHashes,
14081411
FEOpts.shouldTrackSystemDependencies(),
14091412
RequireOSSAModules_t(instance.getSILOptions()));

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ bool ArgsToFrontendOptionsConverter::convert(
6363
if (const Arg *A = Args.getLastArg(OPT_prebuilt_module_cache_path)) {
6464
Opts.PrebuiltModuleCachePath = A->getValue();
6565
}
66+
if (const Arg *A = Args.getLastArg(OPT_backup_module_interface_path)) {
67+
Opts.BackupModuleInterfaceDir = A->getValue();
68+
}
6669
if (const Arg *A = Args.getLastArg(OPT_bridging_header_directory_for_print)) {
6770
Opts.BridgingHeaderDirForPrint = A->getValue();
6871
}

lib/Frontend/CompilerInvocation.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,13 @@ void CompilerInvocation::setDefaultPrebuiltCacheIfNecessary() {
129129

130130
FrontendOpts.PrebuiltModuleCachePath = computePrebuiltCachePath(
131131
SearchPathOpts.RuntimeResourcePath, LangOpts.Target, LangOpts.SDKVersion);
132+
if (!FrontendOpts.PrebuiltModuleCachePath.empty())
133+
return;
134+
StringRef anchor = "prebuilt-modules";
135+
assert(((StringRef)FrontendOpts.PrebuiltModuleCachePath).contains(anchor));
136+
auto pair = ((StringRef)FrontendOpts.PrebuiltModuleCachePath).split(anchor);
137+
FrontendOpts.BackupModuleInterfaceDir =
138+
(llvm::Twine(pair.first) + "preferred-interfaces" + pair.second).str();
132139
}
133140

134141
static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts,

lib/Frontend/Frontend.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,8 @@ bool CompilerInstance::setUpModuleLoaders() {
530530
ModuleInterfaceLoaderOptions LoaderOpts(FEOpts);
531531
Context->addModuleInterfaceChecker(
532532
std::make_unique<ModuleInterfaceCheckerImpl>(
533-
*Context, ModuleCachePath, FEOpts.PrebuiltModuleCachePath, LoaderOpts,
533+
*Context, ModuleCachePath, FEOpts.PrebuiltModuleCachePath,
534+
FEOpts.BackupModuleInterfaceDir, LoaderOpts,
534535
RequireOSSAModules_t(Invocation.getSILOptions())));
535536
// If implicit modules are disabled, we need to install an explicit module
536537
// loader.
@@ -571,10 +572,11 @@ bool CompilerInstance::setUpModuleLoaders() {
571572
auto &FEOpts = Invocation.getFrontendOptions();
572573
ModuleInterfaceLoaderOptions LoaderOpts(FEOpts);
573574
InterfaceSubContextDelegateImpl ASTDelegate(
574-
Context->SourceMgr, Context->Diags, Context->SearchPathOpts,
575+
Context->SourceMgr, &Context->Diags, Context->SearchPathOpts,
575576
Context->LangOpts, Context->ClangImporterOpts, LoaderOpts,
576577
/*buildModuleCacheDirIfAbsent*/ false, ModuleCachePath,
577578
FEOpts.PrebuiltModuleCachePath,
579+
FEOpts.BackupModuleInterfaceDir,
578580
FEOpts.SerializeModuleInterfaceDependencyHashes,
579581
FEOpts.shouldTrackSystemDependencies(),
580582
RequireOSSAModules_t(Invocation.getSILOptions()));

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,11 @@ bool ModuleInterfaceBuilder::collectDepsForSerialization(
103103
// dependency list -- don't serialize that.
104104
if (!prebuiltCachePath.empty() && DepName.startswith(prebuiltCachePath))
105105
continue;
106-
106+
// Don't serialize interface path if it's from the preferred interface dir.
107+
// This ensures the prebuilt module caches generated from these interfaces are
108+
// relocatable.
109+
if (!backupInterfaceDir.empty() && DepName.startswith(backupInterfaceDir))
110+
continue;
107111
if (dependencyTracker) {
108112
dependencyTracker->addDependency(DepName, /*isSystem*/IsSDKRelative);
109113
}

lib/Frontend/ModuleInterfaceBuilder.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ class DependencyTracker;
3535

3636
class ModuleInterfaceBuilder {
3737
SourceManager &sourceMgr;
38-
DiagnosticEngine &diags;
38+
DiagnosticEngine *diags;
3939
InterfaceSubContextDelegate &subASTDelegate;
4040
const StringRef interfacePath;
4141
const StringRef moduleName;
4242
const StringRef moduleCachePath;
4343
const StringRef prebuiltCachePath;
44+
const StringRef backupInterfaceDir;
4445
const bool disableInterfaceFileLock;
4546
const SourceLoc diagnosticLoc;
4647
DependencyTracker *const dependencyTracker;
@@ -50,7 +51,7 @@ class ModuleInterfaceBuilder {
5051
/// Emit a diagnostic tied to this declaration.
5152
template<typename ...ArgTypes>
5253
static InFlightDiagnostic diagnose(
53-
DiagnosticEngine &Diags,
54+
DiagnosticEngine *Diags,
5455
SourceManager &SM,
5556
StringRef InterfacePath,
5657
SourceLoc Loc,
@@ -60,7 +61,7 @@ class ModuleInterfaceBuilder {
6061
// Diagnose this inside the interface file, if possible.
6162
Loc = SM.getLocFromExternalSource(InterfacePath, 1, 1);
6263
}
63-
return Diags.diagnose(Loc, ID, std::move(Args)...);
64+
return Diags->diagnose(Loc, ID, std::move(Args)...);
6465
}
6566

6667
private:
@@ -88,11 +89,12 @@ class ModuleInterfaceBuilder {
8889
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
8990
ArrayRef<std::string> CandidateModules);
9091
public:
91-
ModuleInterfaceBuilder(SourceManager &sourceMgr, DiagnosticEngine &diags,
92+
ModuleInterfaceBuilder(SourceManager &sourceMgr, DiagnosticEngine *diags,
9293
InterfaceSubContextDelegate &subASTDelegate,
9394
StringRef interfacePath,
9495
StringRef moduleName,
9596
StringRef moduleCachePath,
97+
StringRef backupInterfaceDir,
9698
StringRef prebuiltCachePath,
9799
bool disableInterfaceFileLock = false,
98100
SourceLoc diagnosticLoc = SourceLoc(),
@@ -101,6 +103,7 @@ class ModuleInterfaceBuilder {
101103
subASTDelegate(subASTDelegate),
102104
interfacePath(interfacePath), moduleName(moduleName),
103105
moduleCachePath(moduleCachePath), prebuiltCachePath(prebuiltCachePath),
106+
backupInterfaceDir(backupInterfaceDir),
104107
disableInterfaceFileLock(disableInterfaceFileLock),
105108
diagnosticLoc(diagnosticLoc), dependencyTracker(tracker) {}
106109

0 commit comments

Comments
 (0)