Skip to content

Commit e24c9a8

Browse files
authored
Merge pull request #70769 from artemcm/RemapClangDepModuleMapPath
[Dependency Scanning] Use VFS-remapped paths for Clang Module Dependencies' `.modulemap` files
2 parents 4c604b4 + 6c5e884 commit e24c9a8

File tree

3 files changed

+75
-6
lines changed

3 files changed

+75
-6
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2178,6 +2178,7 @@ NOTE(dependency_as_imported_by_main_module,none,
21782178
NOTE(dependency_as_imported_by, none,
21792179
"a dependency of %select{Swift|Clang}2 module '%0': '%1'", (StringRef, StringRef, bool))
21802180
ERROR(clang_dependency_scan_error, none, "Clang dependency scanner failure: %0", (StringRef))
2181+
WARNING(clang_dependency_no_modulemap_fileref, none, "Unable to verify Clang dependency module map '%0': $1", (StringRef, StringRef))
21812182

21822183
// Enum annotations
21832184
ERROR(indirect_case_without_payload,none,

lib/ClangImporter/ClangModuleDependencyScanner.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h"
2626
#include "llvm/ADT/STLExtras.h"
2727
#include "llvm/Support/Allocator.h"
28+
#include "llvm/Support/Error.h"
2829
#include "llvm/Support/FileSystem.h"
2930
#include "llvm/Support/Signals.h"
3031
#include "llvm/Support/Path.h"
@@ -265,17 +266,34 @@ ModuleDependencyVector ClangImporter::bridgeClangModuleDependencies(
265266
swiftArgs.push_back(IncludeTree);
266267
}
267268

269+
// Ensure we get the external path to the modulemap because it is used as an
270+
// explicit input for the resulting compilation task.
271+
auto moduleMapFile =
272+
getClangInstance().getFileManager().getFileRef(
273+
clangModuleDep.ClangModuleMapFile);
274+
StringRef externalModuleMapPath;
275+
if (auto E = moduleMapFile.takeError()) {
276+
ctx.Diags.diagnose(SourceLoc(),
277+
diag::clang_dependency_no_modulemap_fileref,
278+
clangModuleDep.ClangModuleMapFile,
279+
llvm::toString(std::move(E)));
280+
externalModuleMapPath = clangModuleDep.ClangModuleMapFile;
281+
} else
282+
externalModuleMapPath = moduleMapFile.get().getName();
283+
268284
// Module-level dependencies.
269285
llvm::StringSet<> alreadyAddedModules;
270286
auto dependencies = ModuleDependencyInfo::forClangModule(
271-
pcmPath, clangModuleDep.ClangModuleMapFile,
272-
clangModuleDep.ID.ContextHash, swiftArgs, fileDeps, capturedPCMArgs,
273-
RootID, IncludeTree, /*module-cache-key*/ "");
287+
pcmPath, externalModuleMapPath.str(), clangModuleDep.ID.ContextHash,
288+
swiftArgs, fileDeps, capturedPCMArgs, RootID, IncludeTree,
289+
/*module-cache-key*/ "");
274290
for (const auto &moduleName : clangModuleDep.ClangModuleDeps) {
275291
dependencies.addModuleImport(moduleName.ModuleName, &alreadyAddedModules);
276-
// It is safe to assume that all dependencies of a Clang module are Clang modules.
277-
// Doing this allows us to skip "resolving" Clang modules down the line.
278-
dependencies.addModuleDependency({moduleName.ModuleName, ModuleDependencyKind::Clang});
292+
// It is safe to assume that all dependencies of a Clang module are Clang
293+
// modules. Doing this allows us to skip "resolving" Clang modules down
294+
// the line.
295+
dependencies.addModuleDependency(
296+
{moduleName.ModuleName, ModuleDependencyKind::Clang});
279297
}
280298
dependencies.setIsResolved(true);
281299

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/module-cache)
3+
// RUN: %empty-directory(%t/inputs)
4+
// RUN: %empty-directory(%t/remapped)
5+
6+
// RUN: split-file %s %t
7+
// RUN: sed -e "s|TMPDIR|%/t|g" %t/vfs.json.template > %t/inputs/vfs.json
8+
9+
// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/module-cache %t/test.swift -o %t/deps.json -I %/t/inputs -Xcc -ivfsoverlay -Xcc %/t/inputs/vfs.json -vfsoverlay %/t/inputs/vfs.json
10+
// RUN: %validate-json %t/deps.json | %FileCheck %s
11+
12+
//--- remapped/X.h
13+
void funcX(void);
14+
15+
//--- remapped/RedirectedX.modulemap
16+
module RedirectedX {
17+
header "X.h"
18+
export *
19+
}
20+
21+
//--- vfs.json.template
22+
{
23+
"case-sensitive": false,
24+
"version": 0,
25+
"roots": [
26+
{
27+
"type": "directory",
28+
"name": "TMPDIR/inputs",
29+
"contents": [
30+
{
31+
"type": "file",
32+
"name": "module.modulemap",
33+
"external-contents": "TMPDIR/remapped/RedirectedX.modulemap",
34+
},
35+
{
36+
"type": "file",
37+
"name": "X.h",
38+
"external-contents": "TMPDIR/remapped/X.h",
39+
}
40+
]
41+
}
42+
]
43+
}
44+
45+
//--- test.swift
46+
import RedirectedX
47+
48+
// CHECK: "clang": "RedirectedX"
49+
// CHECK: "clang": "RedirectedX"
50+
// CHECK: "moduleMapPath": "{{.*}}{{/|\\}}remapped{{/|\\}}RedirectedX.modulemap",

0 commit comments

Comments
 (0)