Skip to content

Commit 423c482

Browse files
[Caching] Resolve BridgingHeader Module Deps correctly
Fix the bridging header dependencies calculation for explicit module build, especially for caching which needs an accurate list of deps for compute cache key correctly. Previously, the bridging header deps are computed from `ModuleGraph` from the clang dependency scanner, which can be affected by already seen modules. It causes the dependencies to be missing for bridging header if the module is seen by main swift source module. Now report only the directly module dependencies from bridging header, then compute all the transitive dependencies before calculating all the cache keys. rdar://123156636
1 parent 1f4bdd4 commit 423c482

File tree

3 files changed

+91
-11
lines changed

3 files changed

+91
-11
lines changed

lib/ClangImporter/ClangModuleDependencyScanner.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,8 @@ bool ClangImporter::addBridgingHeaderDependencies(
491491

492492
// ... and all module dependencies.
493493
llvm::StringSet<> alreadyAddedModules;
494-
for (const auto &moduleDep : clangModuleDependencies->ModuleGraph)
495-
targetModule.addBridgingModuleDependency(moduleDep.ID.ModuleName,
494+
for (const auto &moduleDep : clangModuleDependencies->ClangModuleDeps)
495+
targetModule.addBridgingModuleDependency(moduleDep.ModuleName,
496496
alreadyAddedModules);
497497

498498
if (auto TreeID = clangModuleDependencies->IncludeTreeID)

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,8 @@ updateModuleCacheKey(ModuleDependencyInfo &depInfo,
193193
static llvm::Error resolveExplicitModuleInputs(
194194
ModuleDependencyID moduleID, const ModuleDependencyInfo &resolvingDepInfo,
195195
const std::set<ModuleDependencyID> &dependencies,
196-
ModuleDependenciesCache &cache, CompilerInstance &instance) {
196+
ModuleDependenciesCache &cache, CompilerInstance &instance,
197+
std::optional<std::set<ModuleDependencyID>> bridgingHeaderDeps) {
197198
// Only need to resolve dependency for following dependencies.
198199
if (moduleID.Kind == ModuleDependencyKind::SwiftPlaceholder)
199200
return llvm::Error::success();
@@ -359,13 +360,11 @@ static llvm::Error resolveExplicitModuleInputs(
359360
dependencyInfoCopy.updateCommandLine(newCommandLine);
360361
}
361362

362-
if (auto *sourceDep = resolvingDepInfo.getAsSwiftSourceModule()) {
363+
if (bridgingHeaderDeps) {
363364
std::vector<std::string> newCommandLine =
364365
dependencyInfoCopy.getBridgingHeaderCommandline();
365-
for (auto bridgingDep :
366-
sourceDep->textualModuleDetails.bridgingModuleDependencies) {
367-
auto dep =
368-
cache.findDependency(bridgingDep, ModuleDependencyKind::Clang);
366+
for (auto bridgingDep : *bridgingHeaderDeps) {
367+
auto dep = cache.findDependency(bridgingDep);
369368
assert(dep && "unknown clang dependency");
370369
auto *clangDep = (*dep)->getAsClangModule();
371370
assert(clangDep && "wrong module dependency kind");
@@ -377,8 +376,8 @@ static llvm::Error resolveExplicitModuleInputs(
377376
newCommandLine.push_back("-Xcc");
378377
newCommandLine.push_back(clangDep->moduleCacheKey);
379378
}
380-
dependencyInfoCopy.updateBridgingHeaderCommandLine(newCommandLine);
381379
}
380+
dependencyInfoCopy.updateBridgingHeaderCommandLine(newCommandLine);
382381
}
383382

384383
if (resolvingDepInfo.isClangModule() ||
@@ -1336,6 +1335,27 @@ computeTransitiveClosureOfExplicitDependencies(
13361335
return result;
13371336
}
13381337

1338+
static std::set<ModuleDependencyID> computeBridgingHeaderTransitiveDependencies(
1339+
const ModuleDependencyInfo *dep,
1340+
const std::unordered_map<ModuleDependencyID, std::set<ModuleDependencyID>>
1341+
&transitiveClosures,
1342+
const ModuleDependenciesCache &cache) {
1343+
std::set<ModuleDependencyID> result;
1344+
auto *sourceDep = dep->getAsSwiftSourceModule();
1345+
if (!sourceDep)
1346+
return result;
1347+
1348+
for (auto &dep : sourceDep->textualModuleDetails.bridgingModuleDependencies) {
1349+
ModuleDependencyID modID{dep, ModuleDependencyKind::Clang};
1350+
result.insert(modID);
1351+
auto succDeps = transitiveClosures.find(modID);
1352+
assert(succDeps != transitiveClosures.end() && "unknown dependency");
1353+
llvm::set_union(result, succDeps->second);
1354+
}
1355+
1356+
return result;
1357+
}
1358+
13391359
static std::vector<ModuleDependencyID>
13401360
findClangDepPath(const ModuleDependencyID &from, const ModuleDependencyID &to,
13411361
ModuleDependenciesCache &cache) {
@@ -1763,8 +1783,14 @@ static void resolveDependencyCommandLineArguments(
17631783
auto optionalDeps = cache.findDependency(modID);
17641784
assert(optionalDeps.has_value());
17651785
auto deps = optionalDeps.value();
1766-
if (auto E = resolveExplicitModuleInputs(modID, *deps, dependencyClosure,
1767-
cache, instance))
1786+
std::optional<std::set<ModuleDependencyID>> bridgingHeaderDeps;
1787+
if (modID.Kind == ModuleDependencyKind::SwiftSource)
1788+
bridgingHeaderDeps = computeBridgingHeaderTransitiveDependencies(
1789+
deps, moduleTransitiveClosures, cache);
1790+
1791+
if (auto E =
1792+
resolveExplicitModuleInputs(modID, *deps, dependencyClosure, cache,
1793+
instance, bridgingHeaderDeps))
17681794
instance.getDiags().diagnose(SourceLoc(), diag::error_cas,
17691795
toString(std::move(E)));
17701796

test/CAS/bridging-header.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -scan-dependencies -module-name Test -module-cache-path %t/clang-module-cache -O \
5+
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
6+
// RUN: %t/test.swift -o %t/deps.json -swift-version 5 -cache-compile-job -cas-path %t/cas \
7+
// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -import-objc-header %t/Bridging.h
8+
9+
// RUN: %{python} %S/Inputs/SwiftDepsExtractor.py %t/deps.json Test bridgingHeader | %FileCheck %s
10+
11+
// CHECK: "includeTree"
12+
// CHECK-NEXT: "moduleDependencies": [
13+
// CHECK-NEXT: "A"
14+
// CHECK-NEXT: ],
15+
// CHECK-NEXT: "commandLine": [
16+
// CHECK: "-fmodule-file-cache-key",
17+
// CHECK-NEXT: "-Xcc",
18+
// CHECK-NEXT: "{{.*}}{{/|\\}}A-{{.*}}.pcm",
19+
// CHECK-NEXT: "-Xcc",
20+
// CHECK-NEXT: "llvmcas://{{.*}}",
21+
// CHECK-NEXT: "-Xcc",
22+
// CHECK-NEXT: "-fmodule-file-cache-key",
23+
// CHECK-NEXT: "-Xcc",
24+
// CHECK-NEXT: "{{.*}}{{/|\\}}B-{{.*}}.pcm",
25+
// CHECK-NEXT: "-Xcc",
26+
// CHECK-NEXT: "llvmcas://{{.*}}"
27+
28+
//--- test.swift
29+
import B
30+
public func test() {}
31+
32+
//--- Bridging.h
33+
#include "Foo.h"
34+
35+
//--- Foo.h
36+
#import "a.h"
37+
38+
//--- a.h
39+
#include "b.h"
40+
41+
//--- b.h
42+
void b(void);
43+
44+
//--- a.modulemap
45+
module A {
46+
header "a.h"
47+
export *
48+
}
49+
50+
//--- b.modulemap
51+
module B {
52+
header "b.h"
53+
export *
54+
}

0 commit comments

Comments
 (0)