mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
ModuleInterface: Setup logic to load swiftinterfaces by default
The Swift compiler can load either the binary swiftmodule file or the textual swiftinterface file when importing a module. It currently picks the swiftmodule over the swiftinterface, unless there’s an exception. We should flip the default for distributed modules, prefer the swiftinterface over the swiftmodule unless there’s an exception. rdar://122955640
This commit is contained in:
@@ -240,12 +240,21 @@ struct ModuleRebuildInfo {
|
||||
InterfacePreferred,
|
||||
CompilerHostModule,
|
||||
Blocklisted,
|
||||
DistributedInterfaceByDefault,
|
||||
};
|
||||
// Keep aligned with diag::module_interface_ignored_reason.
|
||||
enum class ReasonModuleInterfaceIgnored {
|
||||
NotIgnored,
|
||||
LocalModule,
|
||||
Blocklisted,
|
||||
Debugger,
|
||||
};
|
||||
struct CandidateModule {
|
||||
std::string path;
|
||||
llvm::Optional<serialization::Status> serializationStatus;
|
||||
ModuleKind kind;
|
||||
ReasonIgnored reasonIgnored;
|
||||
ReasonModuleInterfaceIgnored reasonModuleInterfaceIgnored;
|
||||
SmallVector<std::string, 10> outOfDateDependencies;
|
||||
SmallVector<std::string, 10> missingDependencies;
|
||||
};
|
||||
@@ -259,6 +268,7 @@ struct ModuleRebuildInfo {
|
||||
llvm::None,
|
||||
ModuleKind::Normal,
|
||||
ReasonIgnored::NotIgnored,
|
||||
ReasonModuleInterfaceIgnored::NotIgnored,
|
||||
{},
|
||||
{}});
|
||||
return candidateModules.back();
|
||||
@@ -290,13 +300,21 @@ struct ModuleRebuildInfo {
|
||||
.missingDependencies.push_back(depPath.str());
|
||||
}
|
||||
|
||||
/// Sets the reason that the module at \c path was ignored. If this is
|
||||
/// Sets the reason that the module at \c modulePath was ignored. If this is
|
||||
/// anything besides \c NotIgnored a note will be added stating why the module
|
||||
/// was ignored.
|
||||
void addIgnoredModule(StringRef modulePath, ReasonIgnored reasonIgnored) {
|
||||
getOrInsertCandidateModule(modulePath).reasonIgnored = reasonIgnored;
|
||||
}
|
||||
|
||||
/// Record why no swiftinterfaces were preferred over the binary swiftmodule
|
||||
/// at \c modulePath.
|
||||
void addIgnoredModuleInterface(StringRef modulePath,
|
||||
ReasonModuleInterfaceIgnored reasonIgnored) {
|
||||
getOrInsertCandidateModule(modulePath).reasonModuleInterfaceIgnored =
|
||||
reasonIgnored;
|
||||
}
|
||||
|
||||
/// Determines if we saw the given module path and registered is as out of
|
||||
/// date.
|
||||
bool sawOutOfDateModule(StringRef modulePath) {
|
||||
@@ -365,7 +383,7 @@ struct ModuleRebuildInfo {
|
||||
// We may have found multiple failing modules, that failed for different
|
||||
// reasons. Emit a note for each of them.
|
||||
for (auto &mod : candidateModules) {
|
||||
// If a the compiled module was ignored, diagnose the reason.
|
||||
// If the compiled module was ignored, diagnose the reason.
|
||||
if (mod.reasonIgnored != ReasonIgnored::NotIgnored) {
|
||||
diags.diagnose(loc, diag::compiled_module_ignored_reason, mod.path,
|
||||
(unsigned)mod.reasonIgnored);
|
||||
@@ -397,6 +415,19 @@ struct ModuleRebuildInfo {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Emits a diagnostic for the reason why binary swiftmodules were preferred
|
||||
/// over textual swiftinterfaces.
|
||||
void diagnoseIgnoredModuleInterfaces(ASTContext &ctx, SourceLoc loc) {
|
||||
for (auto &mod : candidateModules) {
|
||||
auto interfaceIgnore = mod.reasonModuleInterfaceIgnored;
|
||||
if (interfaceIgnore == ReasonModuleInterfaceIgnored::NotIgnored)
|
||||
continue;
|
||||
|
||||
ctx.Diags.diagnose(loc, diag::module_interface_ignored_reason,
|
||||
mod.path, (unsigned)interfaceIgnore);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// Constructs the full path of the dependency \p dep by prepending the SDK
|
||||
@@ -759,6 +790,12 @@ class ModuleInterfaceLoaderImpl {
|
||||
return pathStartsWith(hostPath, path);
|
||||
}
|
||||
|
||||
bool isInSDK(StringRef path) {
|
||||
StringRef sdkPath = ctx.SearchPathOpts.getSDKPath();
|
||||
if (sdkPath.empty()) return false;
|
||||
return pathStartsWith(sdkPath, path);
|
||||
}
|
||||
|
||||
bool isInSystemFrameworks(StringRef path, bool publicFramework) {
|
||||
StringRef sdkPath = ctx.SearchPathOpts.getSDKPath();
|
||||
if (sdkPath.empty()) return false;
|
||||
@@ -773,26 +810,64 @@ class ModuleInterfaceLoaderImpl {
|
||||
|
||||
std::pair<std::string, std::string> getCompiledModuleCandidates() {
|
||||
using ReasonIgnored = ModuleRebuildInfo::ReasonIgnored;
|
||||
using ReasonModuleInterfaceIgnored =
|
||||
ModuleRebuildInfo::ReasonModuleInterfaceIgnored;
|
||||
std::pair<std::string, std::string> result;
|
||||
// Should we attempt to load a swiftmodule adjacent to the swiftinterface?
|
||||
bool shouldLoadAdjacentModule = !ctx.IgnoreAdjacentModules;
|
||||
|
||||
if (modulePath.contains(".sdk")) {
|
||||
if (ctx.blockListConfig.hasBlockListAction(moduleName,
|
||||
BlockListKeyKind::ModuleName, BlockListAction::ShouldUseTextualModule)) {
|
||||
shouldLoadAdjacentModule = false;
|
||||
rebuildInfo.addIgnoredModule(modulePath, ReasonIgnored::Blocklisted);
|
||||
bool ignoreByDefault = ctx.blockListConfig.hasBlockListAction(
|
||||
"Swift_UseSwiftinterfaceByDefault",
|
||||
BlockListKeyKind::ModuleName,
|
||||
BlockListAction::ShouldUseBinaryModule);
|
||||
bool shouldLoadAdjacentModule;
|
||||
if (ignoreByDefault) {
|
||||
ReasonModuleInterfaceIgnored ignore =
|
||||
ReasonModuleInterfaceIgnored::NotIgnored;
|
||||
|
||||
if (!isInSDK(modulePath) &&
|
||||
!isInResourceHostDir(modulePath)) {
|
||||
ignore = ReasonModuleInterfaceIgnored::LocalModule;
|
||||
} else if (ctx.blockListConfig.hasBlockListAction(moduleName,
|
||||
BlockListKeyKind::ModuleName,
|
||||
BlockListAction::ShouldUseBinaryModule)) {
|
||||
ignore = ReasonModuleInterfaceIgnored::Blocklisted;
|
||||
} else if (ctx.LangOpts.DebuggerSupport) {
|
||||
ignore = ReasonModuleInterfaceIgnored::Debugger;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't use the adjacent swiftmodule for frameworks from the public
|
||||
// Frameworks folder of the SDK.
|
||||
if (isInSystemFrameworks(modulePath, /*publicFramework*/true)) {
|
||||
shouldLoadAdjacentModule = false;
|
||||
rebuildInfo.addIgnoredModule(modulePath, ReasonIgnored::PublicFramework);
|
||||
} else if (isInResourceHostDir(modulePath)) {
|
||||
shouldLoadAdjacentModule = false;
|
||||
rebuildInfo.addIgnoredModule(modulePath, ReasonIgnored::CompilerHostModule);
|
||||
shouldLoadAdjacentModule =
|
||||
ignore != ReasonModuleInterfaceIgnored::NotIgnored;
|
||||
if (shouldLoadAdjacentModule) {
|
||||
// Prefer the swiftmodule.
|
||||
rebuildInfo.addIgnoredModuleInterface(modulePath, ignore);
|
||||
} else {
|
||||
// Prefer the swiftinterface.
|
||||
rebuildInfo.addIgnoredModule(modulePath,
|
||||
ReasonIgnored::DistributedInterfaceByDefault);
|
||||
}
|
||||
} else {
|
||||
// Should we attempt to load a swiftmodule adjacent to the swiftinterface?
|
||||
shouldLoadAdjacentModule = !ctx.IgnoreAdjacentModules;
|
||||
|
||||
if (modulePath.contains(".sdk")) {
|
||||
if (ctx.blockListConfig.hasBlockListAction(moduleName,
|
||||
BlockListKeyKind::ModuleName,
|
||||
BlockListAction::ShouldUseTextualModule)) {
|
||||
shouldLoadAdjacentModule = false;
|
||||
rebuildInfo.addIgnoredModule(modulePath, ReasonIgnored::Blocklisted);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't use the adjacent swiftmodule for frameworks from the public
|
||||
// Frameworks folder of the SDK.
|
||||
if (isInSystemFrameworks(modulePath, /*publicFramework*/true)) {
|
||||
shouldLoadAdjacentModule = false;
|
||||
rebuildInfo.addIgnoredModule(modulePath,
|
||||
ReasonIgnored::PublicFramework);
|
||||
} else if (isInResourceHostDir(modulePath)) {
|
||||
shouldLoadAdjacentModule = false;
|
||||
rebuildInfo.addIgnoredModule(modulePath,
|
||||
ReasonIgnored::CompilerHostModule);
|
||||
}
|
||||
}
|
||||
|
||||
switch (loadMode) {
|
||||
@@ -1075,8 +1150,10 @@ class ModuleInterfaceLoaderImpl {
|
||||
// If we errored with anything other than 'no such file or directory',
|
||||
// fail this load and let the other module loader diagnose it.
|
||||
if (!moduleOrErr &&
|
||||
moduleOrErr.getError() != std::errc::no_such_file_or_directory)
|
||||
moduleOrErr.getError() != std::errc::no_such_file_or_directory) {
|
||||
rebuildInfo.diagnoseIgnoredModuleInterfaces(ctx, diagnosticLoc);
|
||||
return moduleOrErr.getError();
|
||||
}
|
||||
|
||||
// We discovered a module! Return that module's buffer so we can load it.
|
||||
if (moduleOrErr) {
|
||||
@@ -1099,6 +1176,7 @@ class ModuleInterfaceLoaderImpl {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return std::move(module.moduleBuffer);
|
||||
}
|
||||
// If building from interface is disabled, return error.
|
||||
|
||||
Reference in New Issue
Block a user