@@ -240,12 +240,21 @@ struct ModuleRebuildInfo {
240240 InterfacePreferred,
241241 CompilerHostModule,
242242 Blocklisted,
243+ DistributedInterfaceByDefault,
244+ };
245+ // Keep aligned with diag::module_interface_ignored_reason.
246+ enum class ReasonModuleInterfaceIgnored {
247+ NotIgnored,
248+ LocalModule,
249+ Blocklisted,
250+ Debugger,
243251 };
244252 struct CandidateModule {
245253 std::string path;
246254 llvm::Optional<serialization::Status> serializationStatus;
247255 ModuleKind kind;
248256 ReasonIgnored reasonIgnored;
257+ ReasonModuleInterfaceIgnored reasonModuleInterfaceIgnored;
249258 SmallVector<std::string, 10 > outOfDateDependencies;
250259 SmallVector<std::string, 10 > missingDependencies;
251260 };
@@ -259,6 +268,7 @@ struct ModuleRebuildInfo {
259268 llvm::None,
260269 ModuleKind::Normal,
261270 ReasonIgnored::NotIgnored,
271+ ReasonModuleInterfaceIgnored::NotIgnored,
262272 {},
263273 {}});
264274 return candidateModules.back ();
@@ -290,13 +300,21 @@ struct ModuleRebuildInfo {
290300 .missingDependencies .push_back (depPath.str ());
291301 }
292302
293- // / Sets the reason that the module at \c path was ignored. If this is
303+ // / Sets the reason that the module at \c modulePath was ignored. If this is
294304 // / anything besides \c NotIgnored a note will be added stating why the module
295305 // / was ignored.
296306 void addIgnoredModule (StringRef modulePath, ReasonIgnored reasonIgnored) {
297307 getOrInsertCandidateModule (modulePath).reasonIgnored = reasonIgnored;
298308 }
299309
310+ // / Record why no swiftinterfaces were preferred over the binary swiftmodule
311+ // / at \c modulePath.
312+ void addIgnoredModuleInterface (StringRef modulePath,
313+ ReasonModuleInterfaceIgnored reasonIgnored) {
314+ getOrInsertCandidateModule (modulePath).reasonModuleInterfaceIgnored =
315+ reasonIgnored;
316+ }
317+
300318 // / Determines if we saw the given module path and registered is as out of
301319 // / date.
302320 bool sawOutOfDateModule (StringRef modulePath) {
@@ -365,7 +383,7 @@ struct ModuleRebuildInfo {
365383 // We may have found multiple failing modules, that failed for different
366384 // reasons. Emit a note for each of them.
367385 for (auto &mod : candidateModules) {
368- // If a the compiled module was ignored, diagnose the reason.
386+ // If the compiled module was ignored, diagnose the reason.
369387 if (mod.reasonIgnored != ReasonIgnored::NotIgnored) {
370388 diags.diagnose (loc, diag::compiled_module_ignored_reason, mod.path ,
371389 (unsigned )mod.reasonIgnored );
@@ -397,6 +415,19 @@ struct ModuleRebuildInfo {
397415 }
398416 }
399417 }
418+
419+ // / Emits a diagnostic for the reason why binary swiftmodules were preferred
420+ // / over textual swiftinterfaces.
421+ void diagnoseIgnoredModuleInterfaces (ASTContext &ctx, SourceLoc loc) {
422+ for (auto &mod : candidateModules) {
423+ auto interfaceIgnore = mod.reasonModuleInterfaceIgnored ;
424+ if (interfaceIgnore == ReasonModuleInterfaceIgnored::NotIgnored)
425+ continue ;
426+
427+ ctx.Diags .diagnose (loc, diag::module_interface_ignored_reason,
428+ mod.path , (unsigned )interfaceIgnore);
429+ }
430+ }
400431};
401432
402433// / Constructs the full path of the dependency \p dep by prepending the SDK
@@ -759,6 +790,12 @@ class ModuleInterfaceLoaderImpl {
759790 return pathStartsWith (hostPath, path);
760791 }
761792
793+ bool isInSDK (StringRef path) {
794+ StringRef sdkPath = ctx.SearchPathOpts .getSDKPath ();
795+ if (sdkPath.empty ()) return false ;
796+ return pathStartsWith (sdkPath, path);
797+ }
798+
762799 bool isInSystemFrameworks (StringRef path, bool publicFramework) {
763800 StringRef sdkPath = ctx.SearchPathOpts .getSDKPath ();
764801 if (sdkPath.empty ()) return false ;
@@ -773,26 +810,64 @@ class ModuleInterfaceLoaderImpl {
773810
774811 std::pair<std::string, std::string> getCompiledModuleCandidates () {
775812 using ReasonIgnored = ModuleRebuildInfo::ReasonIgnored;
813+ using ReasonModuleInterfaceIgnored =
814+ ModuleRebuildInfo::ReasonModuleInterfaceIgnored;
776815 std::pair<std::string, std::string> result;
777- // Should we attempt to load a swiftmodule adjacent to the swiftinterface?
778- bool shouldLoadAdjacentModule = !ctx.IgnoreAdjacentModules ;
779816
780- if (modulePath.contains (" .sdk" )) {
781- if (ctx.blockListConfig .hasBlockListAction (moduleName,
782- BlockListKeyKind::ModuleName, BlockListAction::ShouldUseTextualModule)) {
783- shouldLoadAdjacentModule = false ;
784- rebuildInfo.addIgnoredModule (modulePath, ReasonIgnored::Blocklisted);
817+ bool ignoreByDefault = ctx.blockListConfig .hasBlockListAction (
818+ " Swift_UseSwiftinterfaceByDefault" ,
819+ BlockListKeyKind::ModuleName,
820+ BlockListAction::ShouldUseBinaryModule);
821+ bool shouldLoadAdjacentModule;
822+ if (ignoreByDefault) {
823+ ReasonModuleInterfaceIgnored ignore =
824+ ReasonModuleInterfaceIgnored::NotIgnored;
825+
826+ if (!isInSDK (modulePath) &&
827+ !isInResourceHostDir (modulePath)) {
828+ ignore = ReasonModuleInterfaceIgnored::LocalModule;
829+ } else if (ctx.blockListConfig .hasBlockListAction (moduleName,
830+ BlockListKeyKind::ModuleName,
831+ BlockListAction::ShouldUseBinaryModule)) {
832+ ignore = ReasonModuleInterfaceIgnored::Blocklisted;
833+ } else if (ctx.LangOpts .DebuggerSupport ) {
834+ ignore = ReasonModuleInterfaceIgnored::Debugger;
785835 }
786- }
787836
788- // Don't use the adjacent swiftmodule for frameworks from the public
789- // Frameworks folder of the SDK.
790- if (isInSystemFrameworks (modulePath, /* publicFramework*/ true )) {
791- shouldLoadAdjacentModule = false ;
792- rebuildInfo.addIgnoredModule (modulePath, ReasonIgnored::PublicFramework);
793- } else if (isInResourceHostDir (modulePath)) {
794- shouldLoadAdjacentModule = false ;
795- rebuildInfo.addIgnoredModule (modulePath, ReasonIgnored::CompilerHostModule);
837+ shouldLoadAdjacentModule =
838+ ignore != ReasonModuleInterfaceIgnored::NotIgnored;
839+ if (shouldLoadAdjacentModule) {
840+ // Prefer the swiftmodule.
841+ rebuildInfo.addIgnoredModuleInterface (modulePath, ignore);
842+ } else {
843+ // Prefer the swiftinterface.
844+ rebuildInfo.addIgnoredModule (modulePath,
845+ ReasonIgnored::DistributedInterfaceByDefault);
846+ }
847+ } else {
848+ // Should we attempt to load a swiftmodule adjacent to the swiftinterface?
849+ shouldLoadAdjacentModule = !ctx.IgnoreAdjacentModules ;
850+
851+ if (modulePath.contains (" .sdk" )) {
852+ if (ctx.blockListConfig .hasBlockListAction (moduleName,
853+ BlockListKeyKind::ModuleName,
854+ BlockListAction::ShouldUseTextualModule)) {
855+ shouldLoadAdjacentModule = false ;
856+ rebuildInfo.addIgnoredModule (modulePath, ReasonIgnored::Blocklisted);
857+ }
858+ }
859+
860+ // Don't use the adjacent swiftmodule for frameworks from the public
861+ // Frameworks folder of the SDK.
862+ if (isInSystemFrameworks (modulePath, /* publicFramework*/ true )) {
863+ shouldLoadAdjacentModule = false ;
864+ rebuildInfo.addIgnoredModule (modulePath,
865+ ReasonIgnored::PublicFramework);
866+ } else if (isInResourceHostDir (modulePath)) {
867+ shouldLoadAdjacentModule = false ;
868+ rebuildInfo.addIgnoredModule (modulePath,
869+ ReasonIgnored::CompilerHostModule);
870+ }
796871 }
797872
798873 switch (loadMode) {
@@ -1075,8 +1150,10 @@ class ModuleInterfaceLoaderImpl {
10751150 // If we errored with anything other than 'no such file or directory',
10761151 // fail this load and let the other module loader diagnose it.
10771152 if (!moduleOrErr &&
1078- moduleOrErr.getError () != std::errc::no_such_file_or_directory)
1153+ moduleOrErr.getError () != std::errc::no_such_file_or_directory) {
1154+ rebuildInfo.diagnoseIgnoredModuleInterfaces (ctx, diagnosticLoc);
10791155 return moduleOrErr.getError ();
1156+ }
10801157
10811158 // We discovered a module! Return that module's buffer so we can load it.
10821159 if (moduleOrErr) {
@@ -1099,6 +1176,7 @@ class ModuleInterfaceLoaderImpl {
10991176 }
11001177 }
11011178
1179+
11021180 return std::move (module .moduleBuffer );
11031181 }
11041182 // If building from interface is disabled, return error.
0 commit comments