Skip to content

Commit f76d2c3

Browse files
authored
[ModuleInterface] Short-circuit module loading for frameworks too (#24459)
Follow-up to 7969705 that handles frameworks as well. Oops. rdar://problem/50070463
1 parent 8732188 commit f76d2c3

File tree

3 files changed

+49
-11
lines changed

3 files changed

+49
-11
lines changed

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -264,24 +264,24 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
264264
moduleFramework += ".framework";
265265
isFramework = true;
266266

267-
auto tryFrameworkImport = [&](StringRef frameworkPath) -> bool {
267+
auto tryFrameworkImport = [&](StringRef frameworkPath) -> Optional<bool> {
268268
currPath = frameworkPath;
269269
llvm::sys::path::append(currPath, moduleFramework.str());
270270

271271
// Check if the framework directory exists
272272
if (!fs.exists(currPath)) {
273-
return false;
273+
return None;
274274
}
275275

276276
// Frameworks always use architecture-specific files within a .swiftmodule
277277
// directory.
278278
llvm::sys::path::append(currPath, "Modules", fileNames.module.str());
279-
return findTargetSpecificModuleFiles().getValueOr(false);
279+
return findTargetSpecificModuleFiles();
280280
};
281281

282282
for (const auto &framepath : Ctx.SearchPathOpts.FrameworkSearchPaths) {
283-
if (tryFrameworkImport(framepath.Path))
284-
return true;
283+
if (auto outcome = tryFrameworkImport(framepath.Path))
284+
return outcome.getValue();
285285
}
286286

287287
if (Ctx.LangOpts.Target.isOSDarwin()) {
@@ -290,13 +290,13 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
290290
SmallString<256> scratch;
291291
scratch = Ctx.SearchPathOpts.SDKPath;
292292
llvm::sys::path::append(scratch, "System", "Library", "Frameworks");
293-
if (tryFrameworkImport(scratch))
294-
return true;
293+
if (auto outcome = tryFrameworkImport(scratch))
294+
return outcome.getValue();
295295

296296
scratch = Ctx.SearchPathOpts.SDKPath;
297297
llvm::sys::path::append(scratch, "Library", "Frameworks");
298-
if (tryFrameworkImport(scratch))
299-
return true;
298+
if (auto outcome = tryFrameworkImport(scratch))
299+
return outcome.getValue();
300300
}
301301
}
302302

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %empty-directory(%t/BuildDir/Lib.framework/Modules/Lib.swiftmodule)
2+
// RUN: %empty-directory(%t/SecondBuildDir/Lib.framework/Modules/Lib.swiftmodule)
3+
// RUN: %empty-directory(%t/ModuleCache)
4+
5+
// RUN: echo 'public func showsUpInBothPlaces() {}' > %t/Lib.swift
6+
7+
// 1. Create a .swiftinterface file containing just one API, and put it inside a second build dir (without a .swiftmodule)
8+
// RUN: %target-swift-frontend -typecheck %t/Lib.swift -emit-parseable-module-interface-path %t/SecondBuildDir/Lib.framework/Modules/Lib.swiftmodule/%target-cpu.swiftinterface -module-name Lib
9+
10+
// 2. Add a new API to the module, and compile just the serialized version in the build dir.
11+
// RUN: echo 'public func onlyInTheCompiledModule() {}' >> %t/Lib.swift
12+
// RUN: %target-swift-frontend -emit-module %t/Lib.swift -o %t/BuildDir/Lib.framework/Modules/Lib.swiftmodule/%target-cpu.swiftmodule -emit-parseable-module-interface-path %t/BuildDir/Lib.framework/Modules/Lib.swiftmodule/%target-cpu.swiftinterface -module-name Lib
13+
14+
// 3. Make sure when we compile this test file, we can access both APIs since we'll
15+
// load the compiled .swiftmodule instead of the .swiftinterface in the SDK.
16+
// RUN: %target-swift-frontend -typecheck %s -F %t/BuildDir -F %t/SecondBuildDir -module-cache-path %t/ModuleCache
17+
18+
// 4. Make sure we didn't compile any .swiftinterfaces into the module cache.
19+
// RUN: ls %t/ModuleCache | not grep 'swiftmodule'
20+
21+
// 5. This should also work if the swiftinterface isn't present in the first build dir.
22+
// RUN: rm %t/BuildDir/Lib.framework/Modules/Lib.swiftmodule/%target-cpu.swiftinterface
23+
// RUN: %target-swift-frontend -typecheck %s -F %t/BuildDir -F %t/SecondBuildDir -module-cache-path %t/ModuleCache
24+
25+
// 6. Make sure we /still/ didn't compile any .swiftinterfaces into the module cache.
26+
// RUN: ls %t/ModuleCache | not grep 'swiftmodule'
27+
28+
import Lib
29+
30+
showsUpInBothPlaces()
31+
onlyInTheCompiledModule()

test/ParseableInterface/ModuleCache/prefer-local-module-to-sdk.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// RUN: echo 'public func showsUpInBothPlaces() {}' > %t/Lib.swift
66

77
// 1. Create a .swiftinterface file containing just one API, and put it inside a second build dir (without a .swiftmodule)
8-
// RUN: %target-swift-frontend -typecheck %t/Lib.swift -emit-parseable-module-interface-path %t/SecondBuildDir/Lib.swiftmodule/%target-cpu.swiftinterface
8+
// RUN: %target-swift-frontend -typecheck %t/Lib.swift -emit-parseable-module-interface-path %t/SecondBuildDir/Lib.swiftmodule/%target-cpu.swiftinterface -module-name Lib
99

1010
// 2. Add a new API to the module, and compile just the serialized version in the build dir.
1111
// RUN: echo 'public func onlyInTheCompiledModule() {}' >> %t/Lib.swift
@@ -18,7 +18,14 @@
1818
// 4. Make sure we didn't compile any .swiftinterfaces into the module cache.
1919
// RUN: ls %t/ModuleCache | not grep 'swiftmodule'
2020

21+
// 5. This should also work if the swiftinterface isn't present in the first build dir.
22+
// RUN: rm %t/BuildDir/Lib.swiftinterface
23+
// RUN: %target-swift-frontend -typecheck %s -I %t/BuildDir -I %t/SecondBuildDir -module-cache-path %t/ModuleCache
24+
25+
// 6. Make sure we /still/ didn't compile any .swiftinterfaces into the module cache.
26+
// RUN: ls %t/ModuleCache | not grep 'swiftmodule'
27+
2128
import Lib
2229

2330
showsUpInBothPlaces()
24-
onlyInTheCompiledModule()
31+
onlyInTheCompiledModule()

0 commit comments

Comments
 (0)