summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/FS.cpp
diff options
context:
space:
mode:
authorSam McCall <sam.mccall@gmail.com>2019-07-01 10:11:18 +0000
committerSam McCall <sam.mccall@gmail.com>2019-07-01 10:11:18 +0000
commit9cca81344c861cebe7a11ebefc2d0cf6d180e8cd (patch)
tree92c20358f7d8a217f4e063da8720cfd3ae127a0a /clang-tools-extra/clangd/FS.cpp
parent4f878fe3a7d5f62b726e83bde0a23a268a875734 (diff)
downloadbcm5719-llvm-9cca81344c861cebe7a11ebefc2d0cf6d180e8cd.tar.gz
bcm5719-llvm-9cca81344c861cebe7a11ebefc2d0cf6d180e8cd.zip
[clangd] Make PreambleStatusCache handle filenames more carefully
Summary: - when we hit the cache, the reported filename should be that of the cache query, not that of the cache store. This matches behaviors of common FSes, and avoids triggering difficult edge cases in FileManager when files are being moved around concurrently. - filename comparisons (both cache queries and == mainfile checks) should fold away . and .. in paths. These can appear when relative paths occur in compile_commands.json. (gn does this). Reviewers: kadircet Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D63931 llvm-svn: 364740
Diffstat (limited to 'clang-tools-extra/clangd/FS.cpp')
-rw-r--r--clang-tools-extra/clangd/FS.cpp19
1 files changed, 15 insertions, 4 deletions
diff --git a/clang-tools-extra/clangd/FS.cpp b/clang-tools-extra/clangd/FS.cpp
index aae15b55172..aca9061d5c5 100644
--- a/clang-tools-extra/clangd/FS.cpp
+++ b/clang-tools-extra/clangd/FS.cpp
@@ -10,20 +10,25 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/None.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/VirtualFileSystem.h"
namespace clang {
namespace clangd {
-PreambleFileStatusCache::PreambleFileStatusCache(llvm::StringRef MainFilePath)
- : MainFilePath(MainFilePath) {
+PreambleFileStatusCache::PreambleFileStatusCache(llvm::StringRef MainFilePath){
assert(llvm::sys::path::is_absolute(MainFilePath));
+ llvm::SmallString<256> MainFileCanonical(MainFilePath);
+ llvm::sys::path::remove_dots(MainFileCanonical, /*remove_dot_dot=*/true);
+ this->MainFilePath = MainFileCanonical.str();
}
void PreambleFileStatusCache::update(const llvm::vfs::FileSystem &FS,
llvm::vfs::Status S) {
+ // Canonicalize path for later lookup, which is usually by absolute path.
llvm::SmallString<32> PathStore(S.getName());
if (FS.makeAbsolute(PathStore))
return;
+ llvm::sys::path::remove_dots(PathStore, /*remove_dot_dot=*/true);
// Do not cache status for the main file.
if (PathStore == MainFilePath)
return;
@@ -33,9 +38,15 @@ void PreambleFileStatusCache::update(const llvm::vfs::FileSystem &FS,
llvm::Optional<llvm::vfs::Status>
PreambleFileStatusCache::lookup(llvm::StringRef File) const {
- auto I = StatCache.find(File);
+ // Canonicalize to match the cached form.
+ // Lookup tends to be first by absolute path, so no need to make absolute.
+ llvm::SmallString<256> PathLookup(File);
+ llvm::sys::path::remove_dots(PathLookup, /*remove_dot_dot=*/true);
+
+ auto I = StatCache.find(PathLookup);
if (I != StatCache.end())
- return I->getValue();
+ // Returned Status name should always match the requested File.
+ return llvm::vfs::Status::copyWithNewName(I->getValue(), File);
return None;
}
OpenPOWER on IntegriCloud