Index: clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp =================================================================== --- clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -58,11 +58,47 @@ } std::error_code setCurrentWorkingDirectory(const Twine &Path) override { + assert(llvm::sys::path::is_absolute(Path) && "relative CWD"); CWD = Path.str(); return {}; } + // Provide absolute paths to the underlying FS, to prevent it from using + // the system's CWD. + llvm::ErrorOr status(const Twine &Path) override { + SmallString<256> Storage; + return ProxyFileSystem::status(adjustPath(Path, Storage)); + } + + llvm::ErrorOr> + openFileForRead(const Twine &Path) override { + SmallString<256> Storage; + return ProxyFileSystem::openFileForRead(adjustPath(Path, Storage)); + } + llvm::vfs::directory_iterator dir_begin(const Twine &Dir, + std::error_code &EC) override { + SmallString<256> Storage; + return ProxyFileSystem::dir_begin(adjustPath(Dir, Storage), EC); + } + std::error_code getRealPath(const Twine &Path, + SmallVectorImpl &Output) const override { + SmallString<256> Storage; + return ProxyFileSystem::getRealPath(adjustPath(Path, Storage), Output); + } + std::error_code isLocal(const Twine &Path, bool &Result) override { + SmallString<256> Storage; + return ProxyFileSystem::isLocal(adjustPath(Path, Storage), Result); + } + private: + Twine adjustPath(const Twine &Path, SmallVectorImpl &Storage) const { + assert(!CWD.empty() && "empty CWD"); + + Path.toVector(Storage); + llvm::sys::fs::make_absolute(CWD, Storage); + return Storage; + } + std::string CWD; }; Index: clang/test/ClangScanDeps/Inputs/relative_directory.json =================================================================== --- /dev/null +++ clang/test/ClangScanDeps/Inputs/relative_directory.json @@ -0,0 +1,12 @@ +[ +{ + "directory": "DIR", + "command": "clang -E Inputs/relative_directory_input1.cpp -IInputs", + "file": "DIR/Inputs/relative_directory_input1.cpp" +}, +{ + "directory": "DIR/Inputs", + "command": "clang -E relative_directory_input2.cpp -I.", + "file": "DIR/Inputs/relative_directory_input2.cpp" +} +] Index: clang/test/ClangScanDeps/relative_directory.cpp =================================================================== --- /dev/null +++ clang/test/ClangScanDeps/relative_directory.cpp @@ -0,0 +1,20 @@ +// RUN: rm -rf %t.dir +// RUN: rm -rf %t.cdb +// RUN: mkdir -p %t.dir +// RUN: mkdir %t.dir/Inputs +// RUN: cp %s %t.dir/Inputs/relative_directory_input1.cpp +// RUN: cp %s %t.dir/Inputs/relative_directory_input2.cpp +// RUN: touch %t.dir/Inputs/header.h +// RUN: sed -e "s|DIR|%/t.dir|g" %S/Inputs/relative_directory.json > %t.cdb +// +// RUN: clang-scan-deps -compilation-database %t.cdb -j 1 | FileCheck %s + +#include + +// CHECK: relative_directory_input1.o: +// CHECK-NEXT: relative_directory_input1.cpp +// CHECK-NEXT: header.h + +// CHECK: relative_directory_input2.o: +// CHECK-NEXT: relative_directory_input2.cpp +// CHECK-NEXT: header.h