Skip to content

Commit c298691

Browse files
authored
Merge pull request #8367 from benlangmuir/working-directory-include-tree
[clang][deps][cas] Fix include-tree contents with -working-directory
2 parents e43b134 + 78e64df commit c298691

File tree

6 files changed

+128
-8
lines changed

6 files changed

+128
-8
lines changed

clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ class DependencyScanningAction : public tooling::ToolAction {
420420
}
421421

422422
bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
423-
FileManager *FileMgr,
423+
FileManager *DriverFileMgr,
424424
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
425425
DiagnosticConsumer *DiagConsumer) override {
426426
// Make a deep copy of the original Clang invocation.
@@ -476,12 +476,13 @@ class DependencyScanningAction : public tooling::ToolAction {
476476
ScanInstance.getHeaderSearchOpts().ModulesIncludeVFSUsage =
477477
any(OptimizeArgs & ScanningOptimizations::VFS);
478478

479-
ScanInstance.setFileManager(FileMgr);
480479
// Support for virtual file system overlays.
481-
FileMgr->setVirtualFileSystem(createVFSFromCompilerInvocation(
480+
auto FS = createVFSFromCompilerInvocation(
482481
ScanInstance.getInvocation(), ScanInstance.getDiagnostics(),
483-
FileMgr->getVirtualFileSystemPtr()));
482+
DriverFileMgr->getVirtualFileSystemPtr());
484483

484+
// Create a new FileManager to match the invocation's FileSystemOptions.
485+
auto *FileMgr = ScanInstance.createFileManager(FS);
485486
ScanInstance.createSourceManager(*FileMgr);
486487

487488
// Store the list of prebuilt module files into header search options. This
@@ -868,9 +869,8 @@ bool DependencyScanningWorker::computeDependencies(
868869
ModifiedCommandLine ? *ModifiedCommandLine : CommandLine;
869870
auto &FinalFS = ModifiedFS ? ModifiedFS : BaseFS;
870871

871-
FileSystemOptions FSOpts;
872-
FSOpts.WorkingDir = WorkingDirectory.str();
873-
auto FileMgr = llvm::makeIntrusiveRefCnt<FileManager>(FSOpts, FinalFS);
872+
auto FileMgr =
873+
llvm::makeIntrusiveRefCnt<FileManager>(FileSystemOptions{}, FinalFS);
874874

875875
std::vector<const char *> FinalCCommandLine(FinalCommandLine.size(), nullptr);
876876
llvm::transform(FinalCommandLine, FinalCCommandLine.begin(),

clang/lib/Tooling/DependencyScanning/IncludeTreeActionController.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,18 @@ IncludeTreeBuilder::getObjectForBuffer(const SrcMgr::FileInfo &FI) {
824824

825825
Expected<cas::ObjectRef> IncludeTreeBuilder::addToFileList(FileManager &FM,
826826
FileEntryRef FE) {
827+
SmallString<128> PathStorage;
827828
StringRef Filename = FE.getName();
829+
// Apply -working-directory to relative paths. This option causes filesystem
830+
// lookups to use absolute paths, so make paths in the include-tree filesystem
831+
// absolute to match.
832+
if (!llvm::sys::path::is_absolute(Filename) &&
833+
!FM.getFileSystemOpts().WorkingDir.empty()) {
834+
PathStorage = Filename;
835+
FM.FixupRelativePath(PathStorage);
836+
Filename = PathStorage;
837+
}
838+
828839
llvm::ErrorOr<std::optional<cas::ObjectRef>> CASContents =
829840
FM.getObjectRefForFileContent(Filename);
830841
if (!CASContents)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t/other
3+
// RUN: split-file %s %t
4+
// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
5+
6+
// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-include-tree-full -cas-path %t/cas \
7+
// RUN: > %t/deps.json
8+
9+
// Build the include-tree command
10+
// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu.rsp
11+
// RUN: %clang @%t/tu.rsp -Rcompile-job-cache 2>&1 | FileCheck %s -check-prefix=CACHE-MISS
12+
// RUN: %clang @%t/tu.rsp -Rcompile-job-cache 2>&1 | FileCheck %s -check-prefix=CACHE-HIT
13+
// RUN: ls %t/t.o
14+
15+
// CACHE-MISS: remark: compile job cache miss
16+
// CACHE-HIT: remark: compile job cache hit
17+
18+
// RUN: cat %t/tu.rsp | sed -E 's|.*"-fcas-include-tree" "(llvmcas://[[:xdigit:]]+)".*|\1|' > %t/tu.casid
19+
// RUN: clang-cas-test -cas %t/cas -print-include-tree @%t/tu.casid | FileCheck %s -DPREFIX=%/t
20+
21+
// CHECK: [[PREFIX]]/t.c llvmcas://
22+
// CHECK: 1:1 <built-in> llvmcas://
23+
// CHECK: 2:1 [[PREFIX]]/relative/h1.h llvmcas://
24+
// CHECK: Files:
25+
// CHECK: [[PREFIX]]/t.c llvmcas://
26+
// CHECK: [[PREFIX]]/relative/h1.h llvmcas://
27+
28+
//--- cdb.json.template
29+
[{
30+
"directory": "DIR/other",
31+
"command": "clang -c t.c -I relative -working-directory DIR -o t.o",
32+
"file": "DIR/t.c"
33+
}]
34+
35+
//--- relative/h1.h
36+
37+
//--- t.c
38+
#include "h1.h"
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t/other
3+
// RUN: split-file %s %t
4+
// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
5+
6+
// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-include-tree-full -cas-path %t/cas \
7+
// RUN: > %t/deps.json
8+
9+
// Build the include-tree command
10+
// RUN: %deps-to-rsp %t/deps.json --module H > %t/H.rsp
11+
// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu.rsp
12+
// RUN: %clang @%t/H.rsp -Rcompile-job-cache 2>&1 | FileCheck %s -check-prefix=CACHE-MISS
13+
// RUN: %clang @%t/H.rsp -Rcompile-job-cache 2>&1 | FileCheck %s -check-prefix=CACHE-HIT
14+
// RUN: %clang @%t/tu.rsp -Rcompile-job-cache 2>&1 | FileCheck %s -check-prefix=CACHE-MISS
15+
// RUN: %clang @%t/tu.rsp -Rcompile-job-cache 2>&1 | FileCheck %s -check-prefix=CACHE-HIT
16+
17+
// CACHE-MISS: remark: compile job cache miss
18+
// CACHE-HIT: remark: compile job cache hit
19+
20+
// RUN: cat %t/H.rsp | sed -E 's|.*"-fcas-include-tree" "(llvmcas://[[:xdigit:]]+)".*|\1|' > %t/H.casid
21+
// RUN: clang-cas-test -cas %t/cas -print-include-tree @%t/H.casid | FileCheck %s -DPREFIX=%/t
22+
23+
// CHEK:C <module-includes>
24+
// CHECK: 2:1 [[PREFIX]]/relative/h1.h llvmcas://
25+
// CHECK: Files:
26+
// CHECK: [[PREFIX]]/relative/h1.h llvmcas://
27+
28+
//--- cdb.json.template
29+
[{
30+
"directory": "DIR/other",
31+
"command": "clang -fsyntax-only t.c -I relative -working-directory DIR -fmodules -fimplicit-modules -fimplicit-module-maps",
32+
"file": "DIR/t.c"
33+
}]
34+
35+
//--- relative/h1.h
36+
37+
//--- relative/module.modulemap
38+
module H { header "h1.h" }
39+
40+
//--- t.c
41+
#include "h1.h"
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Test that -working-directory works even when it differs from the working
2+
// directory of the filesystem.
3+
4+
// RUN: rm -rf %t
5+
// RUN: mkdir -p %t/other
6+
// RUN: split-file %s %t
7+
// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
8+
9+
// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full \
10+
// RUN: > %t/deps.json
11+
12+
// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t
13+
14+
// CHECK: "file-deps": [
15+
// CHECK-NEXT: "[[PREFIX]]/cwd/t.c"
16+
// CHECK-NEXT: "[[PREFIX]]/cwd/relative/h1.h"
17+
// CHECK-NEXT: ]
18+
// CHECK-NEXT: "input-file": "[[PREFIX]]/cwd/t.c"
19+
20+
//--- cdb.json.template
21+
[{
22+
"directory": "DIR/other",
23+
"command": "clang -c t.c -I relative -working-directory DIR/cwd",
24+
"file": "DIR/cwd/t.c"
25+
}]
26+
27+
//--- cwd/relative/h1.h
28+
29+
//--- cwd/t.c
30+
#include "h1.h"

clang/unittests/Tooling/DependencyScannerTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,5 +355,5 @@ TEST(DependencyScanner, ScanDepsWithModuleLookup) {
355355

356356
EXPECT_TRUE(llvm::find(InterceptFS->StatPaths, OtherPath) ==
357357
InterceptFS->StatPaths.end());
358-
EXPECT_EQ(InterceptFS->ReadFiles, std::vector<std::string>{"/root/test.m"});
358+
EXPECT_EQ(InterceptFS->ReadFiles, std::vector<std::string>{"test.m"});
359359
}

0 commit comments

Comments
 (0)