Skip to content

Commit 295c845

Browse files
Merge pull request #73601 from cachemeifyoucan/eng/PR-127844120
[ScanDependency] Pass crossimport overlay file to swift-frontend
2 parents 1bee91b + cf8187a commit 295c845

File tree

9 files changed

+118
-25
lines changed

9 files changed

+118
-25
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -812,8 +812,9 @@ class ModuleDependencyInfo {
812812
/// Collect a map from a secondary module name to a list of cross-import
813813
/// overlays, when this current module serves as the primary module.
814814
llvm::StringMap<llvm::SmallSetVector<Identifier, 4>>
815-
collectCrossImportOverlayNames(ASTContext &ctx, StringRef moduleName,
816-
std::vector<std::string> &overlayFiles) const;
815+
collectCrossImportOverlayNames(
816+
ASTContext &ctx, StringRef moduleName,
817+
std::vector<std::pair<std::string, std::string>> &overlayFiles) const;
817818
};
818819

819820
using ModuleDependencyVector = llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>;

include/swift/AST/SearchPathOptions.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,14 @@ class SearchPathOptions {
504504
/// version inheritance.
505505
std::optional<std::string> PlatformAvailabilityInheritanceMapPath;
506506

507+
/// Cross import module information. Map from module name to the list of cross
508+
/// import overlay files that associate with that module.
509+
using CrossImportMap = llvm::StringMap<std::vector<std::string>>;
510+
CrossImportMap CrossImportInfo;
511+
512+
/// Whether to search for cross import overlay on file system.
513+
bool DisableCrossImportOverlaySearch = false;
514+
507515
/// Debug path mappings to apply to serialized search paths. These are
508516
/// specified in LLDB from the target.source-map entries.
509517
PathRemapper SearchPathRemapper;

include/swift/Option/FrontendOptions.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,13 @@ def swift_module_file: Joined<["-"], "swift-module-file=">,
220220
MetaVarName<"<name>=<path>">,
221221
HelpText<"Specify Swift module input explicitly built from textual interface">;
222222

223+
def swift_module_cross_import: MultiArg<["-"], "swift-module-cross-import", 2>,
224+
MetaVarName<"<moduleName> <crossImport.swiftoverlay>">,
225+
HelpText<"Specify the cross import module">;
226+
227+
def disable_cross_import_overlay_search: Flag<["-"], "disable-cross-import-overlay-search">,
228+
HelpText<"Disable searching for cross import overlay file">;
229+
223230
def explicit_swift_module_map
224231
: Separate<["-"], "explicit-swift-module-map-file">, MetaVarName<"<path>">,
225232
HelpText<"Specify a JSON file containing information of explicit Swift modules">;

lib/AST/ModuleLoader.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,19 @@ void ModuleLoader::findOverlayFiles(SourceLoc diagLoc, ModuleDecl *module,
171171
using namespace llvm::sys;
172172
using namespace file_types;
173173

174+
// If cross import information is passed on command-line, prefer use that.
175+
auto &crossImports = module->getASTContext().SearchPathOpts.CrossImportInfo;
176+
auto overlays = crossImports.find(module->getNameStr());
177+
if (overlays != crossImports.end()) {
178+
for (auto entry : overlays->second) {
179+
module->addCrossImportOverlayFile(entry);
180+
if (dependencyTracker)
181+
dependencyTracker->addDependency(entry, module->isSystemModule());
182+
}
183+
}
184+
if (module->getASTContext().SearchPathOpts.DisableCrossImportOverlaySearch)
185+
return;
186+
174187
if (file->getModuleDefiningPath().empty())
175188
return;
176189
findOverlayFilesInternal(module->getASTContext(),
@@ -188,7 +201,7 @@ void ModuleLoader::findOverlayFiles(SourceLoc diagLoc, ModuleDecl *module,
188201
llvm::StringMap<llvm::SmallSetVector<Identifier, 4>>
189202
ModuleDependencyInfo::collectCrossImportOverlayNames(
190203
ASTContext &ctx, StringRef moduleName,
191-
std::vector<std::string> &overlayFiles) const {
204+
std::vector<std::pair<std::string, std::string>> &overlayFiles) const {
192205
using namespace llvm::sys;
193206
using namespace file_types;
194207
std::optional<std::string> modulePath;
@@ -240,7 +253,7 @@ ModuleDependencyInfo::collectCrossImportOverlayNames(
240253
ModuleDecl::collectCrossImportOverlay(ctx, file, moduleName,
241254
bystandingModule);
242255
result[bystandingModule] = std::move(overlayNames);
243-
overlayFiles.push_back(file.str());
256+
overlayFiles.push_back({moduleName.str(), file.str()});
244257
});
245258
return result;
246259
}

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,7 @@ void ModuleDependencyScanner::discoverCrossImportOverlayDependencies(
800800
llvm::function_ref<void(ModuleDependencyID)> action) {
801801
// Modules explicitly imported. Only these can be secondary module.
802802
llvm::SetVector<Identifier> newOverlays;
803-
std::vector<std::string> overlayFiles;
803+
std::vector<std::pair<std::string, std::string>> overlayFiles;
804804
for (auto dep : allDependencies) {
805805
auto moduleName = dep.ModuleName;
806806
// Do not look for overlays of main module under scan
@@ -887,9 +887,15 @@ void ModuleDependencyScanner::discoverCrossImportOverlayDependencies(
887887
mainDep.addModuleDependency(crossImportOverlayModID);
888888
});
889889

890-
llvm::for_each(overlayFiles, [&mainDep](const std::string &file) {
891-
mainDep.addAuxiliaryFile(file);
892-
});
890+
auto cmdCopy = mainDep.getCommandline();
891+
cmdCopy.push_back("-disable-cross-import-overlay-search");
892+
for (auto &entry : overlayFiles) {
893+
mainDep.addAuxiliaryFile(entry.second);
894+
cmdCopy.push_back("-swift-module-cross-import");
895+
cmdCopy.push_back(entry.first);
896+
cmdCopy.push_back(entry.second);
897+
}
898+
mainDep.updateCommandLine(cmdCopy);
893899

894900
cache.updateDependency(
895901
{mainModuleName.str(), ModuleDependencyKind::SwiftSource}, mainDep);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,6 +2091,12 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts, ArgList &Args,
20912091
*forceModuleLoadingMode);
20922092
}
20932093

2094+
for (auto *A : Args.filtered(OPT_swift_module_cross_import))
2095+
Opts.CrossImportInfo[A->getValue(0)].push_back(A->getValue(1));
2096+
2097+
Opts.DisableCrossImportOverlaySearch |=
2098+
Args.hasArg(OPT_disable_cross_import_overlay_search);
2099+
20942100
// Opts.RuntimeIncludePath is set by calls to
20952101
// setRuntimeIncludePath() or setMainExecutablePath().
20962102
// Opts.RuntimeImportPath is set by calls to

test/CAS/cross_import.swift

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,38 @@
55
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \
66
// RUN: -emit-module-interface-path %t/A.swiftinterface -enable-library-evolution -I %t %t/A.swift
77

8-
// RUN: %target-swift-frontend -emit-module -module-name B -o %t/A.swiftmodule -swift-version 5 \
8+
// RUN: %target-swift-frontend -emit-module -module-name B -o %t/B.swiftmodule -swift-version 5 \
99
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \
1010
// RUN: -emit-module-interface-path %t/B.swiftinterface -enable-library-evolution -I %t %t/B.swift
1111

12-
// RUN: %target-swift-frontend -emit-module -module-name _Cross -o %t/A.swiftmodule -swift-version 5 \
12+
// RUN: %target-swift-frontend -emit-module -module-name _B_A -o %t/_B_A.swiftmodule -swift-version 5 \
1313
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \
14-
// RUN: -emit-module-interface-path %t/_Cross.swiftinterface -enable-library-evolution -I %t %t/cross.swift
14+
// RUN: -emit-module-interface-path %t/_B_A.swiftinterface -enable-library-evolution -I %t %t/b_a.swift
1515

16-
// RUN: %target-swift-frontend -scan-dependencies -module-name Test -module-cache-path %t/clang-module-cache %t/main.swift \
16+
// RUN: %target-swift-frontend -emit-module -module-name _C_A -o %t/_C_A.swiftmodule -swift-version 5 \
1717
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \
18-
// RUN: -o %t/deps.json -I %t -cache-compile-job -cas-path %t/cas -swift-version 5 -enable-cross-import-overlays -module-load-mode prefer-interface
18+
// RUN: -emit-module-interface-path %t/_C_A.swiftinterface -enable-library-evolution -I %t %t/c_a.swift
1919

20-
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json A > %t/A.cmd
21-
// RUN: %swift_frontend_plain @%t/A.cmd
22-
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json B > %t/B.cmd
23-
// RUN: %swift_frontend_plain @%t/B.cmd
24-
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json _Cross > %t/Cross.cmd
25-
// RUN: %swift_frontend_plain @%t/Cross.cmd
20+
// RUN: %target-swift-frontend -scan-dependencies -module-name Test -module-cache-path %t/clang-module-cache %t/main.swift -F %t \
21+
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -O \
22+
// RUN: -o %t/deps.json -I %t -cache-compile-job -cas-path %t/cas -swift-version 5 -enable-cross-import-overlays -module-load-mode prefer-serialized
2623

27-
// RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json
24+
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:SwiftShims > %t/shim.cmd
25+
// RUN: %swift_frontend_plain @%t/shim.cmd
26+
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:C > %t/C.cmd
27+
// RUN: %swift_frontend_plain @%t/C.cmd
28+
29+
// RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json %t > %t/map.json
2830
// RUN: llvm-cas --cas %t/cas --make-blob --data %t/map.json > %t/map.casid
2931

3032
// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json Test > %t/MyApp.cmd
33+
// RUN: %FileCheck %s --input-file=%t/MyApp.cmd --check-prefix CMD
34+
// CMD: -swift-module-cross-import
35+
// CMD-NEXT: B
36+
// CMD-NEXT: A.swiftoverlay
37+
// CMD-NEXT: -swift-module-cross-import
38+
// CMD-NEXT: C
39+
// CMD-NEXT: A.swiftoverlay
3140

3241
// RUN: %target-swift-frontend -emit-module -o %t/Test.swiftmodule \
3342
// RUN: -emit-module-interface-path %t/Test.swiftinterface \
@@ -40,28 +49,50 @@
4049
// RUN: %FileCheck %s --input-file=%t/Test.swiftinterface
4150

4251
/// Check to make sure the implicit cross import turned into explicit import in the interface file.
43-
// CHECK: import _Cross
52+
// CHECK: import _B_A
53+
// CHECK: import _C_A
4454

4555
//--- A.swift
4656
public func a() {}
4757

4858
//--- B.swift
4959
public func b() {}
5060

51-
//--- cross.swift
52-
public func cross() {}
61+
//--- b_a.swift
62+
public func b_a() {}
63+
64+
//--- c_a.swift
65+
public func c_a() {}
66+
67+
//--- C.framework/Modules/module.modulemap
68+
framework module C {
69+
umbrella header "C.h"
70+
export *
71+
}
72+
73+
//--- C.framework/Headers/C.h
74+
void c(void);
75+
76+
//--- C.framework/Modules/C.swiftcrossimport/A.swiftoverlay
77+
%YAML 1.2
78+
---
79+
version: 1
80+
modules:
81+
- name: _C_A
5382

5483
//--- main.swift
5584
import A
5685
import B
86+
import C
5787

5888
func test () {
59-
cross()
89+
b_a()
90+
c_a()
6091
}
6192

6293
//--- B.swiftcrossimport/A.swiftoverlay
6394
%YAML 1.2
6495
---
6596
version: 1
6697
modules:
67-
- name: _Cross
98+
- name: _B_A
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// This file tests that the -Rcross-import option causes an appropriate remark to be emitted
2+
// RUN: %empty-directory(%t)
3+
// RUN: cp -r %S/Inputs/lib-templates/* %t/
4+
// RUN: %target-swift-frontend -typecheck %s -enable-cross-import-overlays -Rcross-import -I %t/include -I %t/lib/swift -F %t/Frameworks 2>&1 | %FileCheck %s -check-prefix IMPORT
5+
// RUN: %target-swift-frontend -typecheck %s -disable-cross-import-overlay-search -enable-cross-import-overlays -Rcross-import -I %t/include -I %t/lib/swift -F %t/Frameworks 2>&1 \
6+
// RUN: | %FileCheck %s -check-prefix NO-IMPORT -allow-empty
7+
// RUN: %target-swift-frontend -typecheck %s -disable-cross-import-overlay-search -enable-cross-import-overlays -Rcross-import -I %t/include -I %t/lib/swift -F %t/Frameworks 2>&1 \
8+
// RUN: -swift-module-cross-import DeclaringLibrary %t/lib/swift/DeclaringLibrary.swiftcrossimport/BystandingLibrary.swiftoverlay | %FileCheck %s -check-prefix IMPORT
9+
10+
import DeclaringLibrary
11+
import BystandingLibrary
12+
13+
// IMPORT: import of 'DeclaringLibrary' and 'BystandingLibrary' triggered a cross-import of '_OverlayLibrary'
14+
// NO-IMPORT-NOT: import of 'DeclaringLibrary' and 'BystandingLibrary' triggered a cross-import of '_OverlayLibrary'

test/ScanDependencies/module_deps_cross_import_overlay.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,12 @@ import SubEWrapper
3030
// CHECK-NOT: "clang": "X"
3131
// CHECK: ],
3232

33+
// CHECK: "swift": {
34+
// CHECK-NEXT: "commandLine": [
35+
// CHECK-NEXT: "-disable-cross-import-overlay-search",
36+
// CHECK-NEXT: "-swift-module-cross-import",
37+
// CHECK-NEXT: "E",
38+
// CHECK-NEXT: SubE.swiftoverlay
39+
3340
// Ensure a transitive dependency via "_cross_import_E" is recorded in the graph still
3441
// CHECK: "clang": "X"

0 commit comments

Comments
 (0)