Skip to content

Commit 62720a3

Browse files
authored
Merge pull request #8379 from benlangmuir/working-directory-include-tree-stable
[stable/2023025][clang][deps][cas] Fix include-tree contents with -working-directory
2 parents bdf4627 + 564c472 commit 62720a3

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
@@ -421,7 +421,7 @@ class DependencyScanningAction : public tooling::ToolAction {
421421
}
422422

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

480-
ScanInstance.setFileManager(FileMgr);
481480
// Support for virtual file system overlays.
482-
FileMgr->setVirtualFileSystem(createVFSFromCompilerInvocation(
481+
auto FS = createVFSFromCompilerInvocation(
483482
ScanInstance.getInvocation(), ScanInstance.getDiagnostics(),
484-
FileMgr->getVirtualFileSystemPtr()));
483+
DriverFileMgr->getVirtualFileSystemPtr());
485484

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

488489
// Store the list of prebuilt module files into header search options. This
@@ -845,9 +846,8 @@ bool DependencyScanningWorker::computeDependencies(
845846
ModifiedCommandLine ? *ModifiedCommandLine : CommandLine;
846847
auto &FinalFS = ModifiedFS ? ModifiedFS : BaseFS;
847848

848-
FileSystemOptions FSOpts;
849-
FSOpts.WorkingDir = WorkingDirectory.str();
850-
auto FileMgr = llvm::makeIntrusiveRefCnt<FileManager>(FSOpts, FinalFS);
849+
auto FileMgr =
850+
llvm::makeIntrusiveRefCnt<FileManager>(FileSystemOptions{}, FinalFS);
851851

852852
std::vector<const char *> FinalCCommandLine(FinalCommandLine.size(), nullptr);
853853
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
@@ -816,7 +816,18 @@ IncludeTreeBuilder::getObjectForBuffer(const SrcMgr::FileInfo &FI) {
816816

817817
Expected<cas::ObjectRef>
818818
IncludeTreeBuilder::addToFileList(FileManager &FM, const FileEntry *FE) {
819+
SmallString<128> PathStorage;
819820
StringRef Filename = FE->getName();
821+
// Apply -working-directory to relative paths. This option causes filesystem
822+
// lookups to use absolute paths, so make paths in the include-tree filesystem
823+
// absolute to match.
824+
if (!llvm::sys::path::is_absolute(Filename) &&
825+
!FM.getFileSystemOpts().WorkingDir.empty()) {
826+
PathStorage = Filename;
827+
FM.FixupRelativePath(PathStorage);
828+
Filename = PathStorage;
829+
}
830+
820831
llvm::ErrorOr<std::optional<cas::ObjectRef>> CASContents =
821832
FM.getObjectRefForFileContent(Filename);
822833
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)