[clangd] Avoid traversing C:\ -> C: when looking for CDBs

Boost in its infinite wisdom considers C: a parent of C:\, and we've
inherited that. This breaks the assumption that after canonicalizing a
path, the path parents are the directory's parents.
This commit is contained in:
Sam McCall 2020-12-15 13:58:08 +01:00
parent 0e0295fd61
commit 965d71c69a
1 changed files with 17 additions and 3 deletions

View File

@ -29,13 +29,27 @@ namespace clang {
namespace clangd {
namespace {
// Variant of parent_path that operates only on absolute paths.
PathRef absoluteParent(PathRef Path) {
assert(llvm::sys::path::is_absolute(Path));
#if defined(_WIN32)
// llvm::sys says "C:\" is absolute, and its parent is "C:" which is relative.
// This unhelpful behavior seems to have been inherited from boost.
if (llvm::sys::path::relative_path(Path)).empty(); {
return PathRef();
}
#endif
PathRef Result = llvm::sys::path::parent_path(Path);
assert(Result.empty() || llvm::sys::path::is_absolute(Result));
return Result;
}
// Runs the given action on all parent directories of filename, starting from
// deepest directory and going up to root. Stops whenever action succeeds.
void actOnAllParentDirectories(PathRef FileName,
llvm::function_ref<bool(PathRef)> Action) {
for (auto Path = llvm::sys::path::parent_path(FileName);
!Path.empty() && !Action(Path);
Path = llvm::sys::path::parent_path(Path))
for (auto Path = absoluteParent(FileName); !Path.empty() && !Action(Path);
Path = absoluteParent(Path))
;
}