Skip to content
Open
7 changes: 7 additions & 0 deletions clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,13 @@ void ModuleDepCollectorPP::EndOfMainFile() {
if (!MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude.empty())
MDC.addFileDep(MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude);

if (Module *CurrentModule = PP.getCurrentModuleImplementation()) {
if (OptionalFileEntryRef CurrentModuleMap =
PP.getHeaderSearchInfo().getModuleMap().getModuleMapFileForUniquing(
CurrentModule))
MDC.addFileDep(CurrentModuleMap->getName());
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With ->getName() I have

  Failed Tests (1):
    Clang :: ClangScanDeps/modules-current-modulemap-file-dep.c

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The failure is expected. The "file-deps" field is intended for consumption by tools that might not understand Clang's virtual filesystem overlays, so the only thing they can reason about is the on-disk path for files ("external-contents" in the VFS overlay file). That's of course different from what we put on the command-line for Clang itself, as Ben explained above.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's take a step back. What use cases do you have for "file-deps"? Because I've realized that for reproducers I'm not interested in the output paths to process them somehow. Actually, I want to take the paths and provide them to the compiler as the input.

I'm considering if we should have 2 flavours of file dependencies - one before all the file system remappings and one after clang applied the remappings.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build system uses file-deps to check their modification time during incremental builds and figure out what needs to be recompiled.

What do you mean by input and output paths? All file dependencies are inputs currently.

How do you plan to feed the list of files to the compiler?

}

for (const Module *M :
MDC.ScanInstance.getPreprocessor().getAffectingClangModules())
if (!MDC.isPrebuiltModule(M))
Expand Down
55 changes: 55 additions & 0 deletions clang/test/ClangScanDeps/modules-current-modulemap-file-dep.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// RUN: rm -rf %t
// RUN: split-file %s %t

// RUN: sed -e "s|DIR|%/t|g" %t/vfs.yaml.in > %t/vfs.yaml

// RUN: clang-scan-deps -format experimental-full -j 1 -- \
// RUN: %clang -ivfsoverlay %t/vfs.yaml -fmodules -fimplicit-module-maps \
// RUN: -fmodules-cache-path=%t/cache -fmodule-name=ModuleName \
// RUN: -I %/t/remapped -c %t/header-impl.c -o %t/header-impl.o \
// RUN: | FileCheck %s -DPREFIX=%/t

// CHECK: "command-line": [
// CHECK: "-fmodule-map-file=[[PREFIX]]/remapped/module.modulemap"
// CHECK: "file-deps": [
// CHECK: "[[PREFIX]]/remapped/module.modulemap"

//--- vfs.yaml.in
{
"version": 0,
"case-sensitive": "false",
"roots": [
{
"name": "DIR/remapped",
"type": "directory",
"contents": [
{
"name": "module.modulemap",
"type": "file",
"external-contents": "DIR/original/module.modulemap"
},
{
"name": "header.h",
"type": "file",
"external-contents": "DIR/original/header.h"
}
]
}
]
}

//--- original/module.modulemap
module ModuleName {
header "header.h"
export *
}

//--- original/header.h
int foo_function(void);

//--- header-impl.c
#include <header.h>

int foo_function(void) {
return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
// CHECK: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/modules-fmodule-name-no-module-built.m",
// CHECK-NEXT: "[[PREFIX]]/Inputs/header3.h",
// CHECK-NEXT: "[[PREFIX]]/Inputs/header.h"
// CHECK-NEXT: "[[PREFIX]]/Inputs/header.h",
// CHECK-NEXT: "[[PREFIX]]/Inputs/module.modulemap"
// CHECK-NEXT: ],
// CHECK-NEXT: "input-file": "[[PREFIX]]/modules-fmodule-name-no-module-built.m"
// CHECK-NEXT: }
3 changes: 2 additions & 1 deletion clang/test/ClangScanDeps/modules-header-sharing.m
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@
// CHECK: ],
// CHECK: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/tu.m",
// CHECK-NEXT: "[[PREFIX]]/shared/H.h"
// CHECK-NEXT: "[[PREFIX]]/shared/H.h",
// CHECK-NEXT: "[[PREFIX]]/frameworks/A.framework/Modules/module.modulemap"
// CHECK-NEXT: ],
// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.m"
// CHECK-NEXT: }
Expand Down
3 changes: 2 additions & 1 deletion clang/test/ClangScanDeps/modules-implementation-module-map.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ framework module FWPrivate { header "private.h" }
// CHECK: "-fmodule-name=FWPrivate",
// CHECK: ],
// CHECK: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/tu.m"
// CHECK-NEXT: "[[PREFIX]]/tu.m",
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.private.modulemap"
// CHECK-NEXT: ],
// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.m"
// CHECK-NEXT: }
Expand Down
3 changes: 2 additions & 1 deletion clang/test/ClangScanDeps/modules-implementation-private.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
// CHECK: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/tu.m",
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/Missed.h",
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Headers/FW.h"
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Headers/FW.h",
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.modulemap"
// CHECK-NEXT: ],
// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.m"
// CHECK-NEXT: }
Expand Down
Loading