Skip to content

Commit 1608523

Browse files
committed
[Serialization] Always serialize module-defining '.swiftinterface', even if SDK-relative.
The clients, upon loading, will resolve the SDK-relative path to their SDK location. Resolves rdar://120673684
1 parent 556a9b1 commit 1608523

File tree

4 files changed

+59
-3
lines changed

4 files changed

+59
-3
lines changed

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,12 @@ std::error_code ExplicitModuleInterfaceBuilder::buildSwiftModuleFromInterface(
275275
!Invocation.getIRGenOptions().ForceLoadSymbolName.empty();
276276
SerializationOpts.UserModuleVersion = FEOpts.UserModuleVersion;
277277
SerializationOpts.AllowableClients = FEOpts.AllowableClients;
278-
279-
// Record any non-SDK module interface files for the debug info.
280278
StringRef SDKPath = Instance.getASTContext().SearchPathOpts.getSDKPath();
281-
if (!getRelativeDepPath(InPath, SDKPath))
279+
280+
auto SDKRelativePath = getRelativeDepPath(InPath, SDKPath);
281+
if (SDKRelativePath.has_value())
282+
SerializationOpts.ModuleInterface = SDKRelativePath.value();
283+
else
282284
SerializationOpts.ModuleInterface = InPath;
283285

284286
SerializationOpts.SDKName = Instance.getASTContext().LangOpts.SDKName;

lib/Serialization/ModuleFile.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,19 @@ static bool isTargetTooNew(const llvm::Triple &moduleTarget,
9191
return ctxTarget.isOSVersionLT(moduleTarget);
9292
}
9393

94+
std::string ModuleFile::resolveModuleDefiningFilename(const ASTContext &ctx) {
95+
if (!Core->ModuleInterfacePath.empty()) {
96+
std::string interfacePath = Core->ModuleInterfacePath.str();
97+
if (llvm::sys::path::is_relative(interfacePath)) {
98+
SmallString<128> absoluteInterfacePath(ctx.SearchPathOpts.getSDKPath());
99+
llvm::sys::path::append(absoluteInterfacePath, interfacePath);
100+
return absoluteInterfacePath.str().str();
101+
} else
102+
return interfacePath;
103+
} else
104+
return getModuleLoadedFilename().str();
105+
}
106+
94107
namespace swift {
95108
namespace serialization {
96109
bool areCompatible(const llvm::Triple &moduleTarget,
@@ -257,6 +270,8 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc,
257270
}
258271

259272
ASTContext &ctx = getContext();
273+
// Resolve potentially-SDK-relative module-defining .swiftinterface path
274+
ResolvedModuleDefiningFilename = resolveModuleDefiningFilename(ctx);
260275

261276
llvm::Triple moduleTarget(llvm::Triple::normalize(Core->TargetTriple));
262277
if (!areCompatible(moduleTarget, ctx.LangOpts.Target)) {

lib/Serialization/ModuleFile.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ class ModuleFile
7474
/// The module that this module is an overlay of, if any.
7575
ModuleDecl *UnderlyingModule = nullptr;
7676

77+
/// Once this module file has been associated with the AST node representing
78+
/// it, resolve the potentially-SDK-relative module-defining `.swiftinterface`
79+
/// path to an absolute path.
80+
llvm::Optional<std::string> ResolvedModuleDefiningFilename;
81+
7782
/// The cursor used to lazily load things from the file.
7883
llvm::BitstreamCursor DeclTypeCursor;
7984

@@ -280,6 +285,10 @@ class ModuleFile
280285
ArrayRef<ProtocolConformanceID>
281286
claimLazyConformanceLoaderToken(uint64_t token);
282287

288+
/// If the module-defining `.swiftinterface` file is an SDK-relative path,
289+
/// resolve it to be absolute to the context's SDK.
290+
std::string resolveModuleDefiningFilename(const ASTContext &ctx);
291+
283292
/// Represents an identifier that may or may not have been deserialized yet.
284293
///
285294
/// If \c Ident is empty, the identifier has not been loaded yet.
@@ -849,6 +858,8 @@ class ModuleFile
849858
void getDisplayDecls(SmallVectorImpl<Decl*> &results, bool recursive = false);
850859

851860
StringRef getModuleFilename() const {
861+
if (ResolvedModuleDefiningFilename)
862+
return ResolvedModuleDefiningFilename.value();
852863
if (!Core->ModuleInterfacePath.empty())
853864
return Core->ModuleInterfacePath;
854865
return getModuleLoadedFilename();
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/inputs)
3+
// RUN: %empty-directory(%t/test-sdk)
4+
// RUN: %empty-directory(%t/test-sdk/usr/lib/Foo.swiftmodule)
5+
// RUN: split-file %s %t
6+
7+
// --- Verify that a non-SDK module gets its absolute path serialized into the binary '.swiftmodule'
8+
// RUN: %target-swift-frontend -compile-module-from-interface -module-name Foo %t/modules/Foo.swiftinterface -o %t/inputs/Foo.swiftmodule
9+
// RUN: llvm-bcanalyzer -dump %t/inputs/Foo.swiftmodule > %t/Foo.freestanding.moduledump.txt
10+
// RUN: cat %t/Foo.freestanding.moduledump.txt | %FileCheck %s -check-prefix CHECK-FREESTANDING-FOO
11+
12+
// --- Verify that an SDK module gets its SDK-relative path serialized into the binary '.swiftmodule'
13+
// RUN: cp %t/modules/Foo.swiftinterface %t/test-sdk/usr/lib/Foo.swiftmodule
14+
// RUN: %target-swift-frontend(mock-sdk: -sdk %t/test-sdk) -compile-module-from-interface -module-name Foo %t/test-sdk/usr/lib/Foo.swiftmodule/Foo.swiftinterface -o %t/inputs/SDKFoo.swiftmodule
15+
// RUN: llvm-bcanalyzer -dump %t/inputs/SDKFoo.swiftmodule > %t/Foo.sdk.moduledump.txt
16+
// RUN: cat %t/Foo.SDK.moduledump.txt | %FileCheck %s -check-prefix CHECK-SDK-FOO
17+
18+
// CHECK-FREESTANDING-FOO: <MODULE_INTERFACE_PATH abbrevid={{[0-9]+}}/> blob data = '{{.*}}{{/|\\}}modules{{/|\\}}Foo.swiftinterface'
19+
// CHECK-SDK-FOO: <MODULE_INTERFACE_PATH abbrevid={{[0-9]+}}/> blob data = 'usr/lib/Foo.swiftmodule/Foo.swiftinterface'
20+
21+
//--- modules/Foo.swiftinterface
22+
// swift-interface-format-version: 1.0
23+
// swift-module-flags: -module-name Foo
24+
public func foo()
25+
26+
//--- File.swift
27+
import Foo
28+
public func bar() { foo() }

0 commit comments

Comments
 (0)