[Clang][ScanDeps] Use the virtual path for module maps
authorMichael Spencer <bigcheesegs@gmail.com>
Tue, 14 Dec 2021 18:18:31 +0000 (11:18 -0700)
committerMichael Spencer <michael_spencer@apple.com>
Tue, 14 Dec 2021 18:21:42 +0000 (11:21 -0700)
Make clang-scan-deps use the virtual path for module maps instead of the on disk
path. This is needed so that modulemap relative lookups are done correctly in
the actual module builds. The file dependencies still use the on disk path as
that's what matters for build invalidation.

Differential Revision: https://reviews.llvm.org/D114206

clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
clang/test/ClangScanDeps/modulemap-via-vfs.m [new file with mode: 0644]

index 9229c67..086215e 100644 (file)
@@ -237,7 +237,13 @@ ModuleID ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
                                    .getHeaderSearchInfo()
                                    .getModuleMap()
                                    .getModuleMapFileForUniquing(M);
-  MD.ClangModuleMapFile = std::string(ModuleMap ? ModuleMap->getName() : "");
+
+  if (ModuleMap) {
+    StringRef Path = ModuleMap->tryGetRealPathName();
+    if (Path.empty())
+      Path = ModuleMap->getName();
+    MD.ClangModuleMapFile = std::string(Path);
+  }
 
   serialization::ModuleFile *MF =
       MDC.ScanInstance.getASTReader()->getModuleManager().lookup(
diff --git a/clang/test/ClangScanDeps/modulemap-via-vfs.m b/clang/test/ClangScanDeps/modulemap-via-vfs.m
new file mode 100644 (file)
index 0000000..cc152b6
--- /dev/null
@@ -0,0 +1,56 @@
+// RUN: rm -rf %t.dir
+// RUN: split-file %s %t.dir
+// RUN: sed -e "s|DIR|%/t.dir|g" %t.dir/build/compile-commands.json.in > %t.dir/build/compile-commands.json
+// RUN: sed -e "s|DIR|%/t.dir|g" %t.dir/build/vfs.yaml.in > %t.dir/build/vfs.yaml
+// RUN: clang-scan-deps -compilation-database %t.dir/build/compile-commands.json -j 1 -format experimental-full \
+// RUN:   -mode preprocess-minimized-sources -generate-modules-path-args > %t.db
+// RUN: %python %S/../../utils/module-deps-to-rsp.py %t.db --module-name=A > %t.A.cc1.rsp
+// RUN: cat %t.A.cc1.rsp | sed 's:\\\\\?:/:g' | FileCheck %s
+
+// CHECK-NOT: build/module.modulemap
+// CHECK: A/module.modulemap
+
+//--- build/compile-commands.json.in
+
+[
+{
+  "directory": "DIR",
+  "command": "clang DIR/main.m -Imodules/A -fmodules -fmodules-cache-path=module-cache -fimplicit-modules -fimplicit-module-maps -ivfsoverlay build/vfs.yaml",
+  "file": "DIR/main.m"
+}
+]
+
+//--- build/module.modulemap
+
+module A {
+  umbrella header "A.h"
+}
+
+//--- modules/A/A.h
+
+typedef int A_t;
+
+//--- build/vfs.yaml.in
+
+{
+  "version": 0,
+  "case-sensitive": "false",
+  "roots": [
+  {
+     "contents": [
+     {
+        "external-contents": "DIR/build/module.modulemap",
+        "name": "module.modulemap",
+        "type": "file"
+     }],
+     "name": "DIR/modules/A",
+     "type": "directory"
+  }
+  ]
+}
+
+//--- main.m
+
+@import A;
+
+A_t a = 0;