Skip to content

Commit 6329ce7

Browse files
committed
[clangd] Expose absoluteParent helper
Will be used in other components that need ancestor traversal. Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D96123
1 parent c1664c5 commit 6329ce7

File tree

5 files changed

+27
-38
lines changed

5 files changed

+27
-38
lines changed

clang-tools-extra/clangd/ConfigProvider.cpp

+6-10
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
#include "Config.h"
1111
#include "ConfigFragment.h"
1212
#include "support/FileCache.h"
13+
#include "support/Path.h"
1314
#include "support/ThreadsafeFS.h"
1415
#include "support/Trace.h"
16+
#include "llvm/ADT/STLExtras.h"
1517
#include "llvm/ADT/ScopeExit.h"
1618
#include "llvm/ADT/StringMap.h"
1719
#include "llvm/ADT/StringRef.h"
@@ -96,16 +98,10 @@ Provider::fromAncestorRelativeYAMLFiles(llvm::StringRef RelPath,
9698
return {};
9799

98100
// Compute absolute paths to all ancestors (substrings of P.Path).
99-
llvm::StringRef Parent = path::parent_path(P.Path);
100101
llvm::SmallVector<llvm::StringRef, 8> Ancestors;
101-
for (auto I = path::begin(Parent, path::Style::posix),
102-
E = path::end(Parent);
103-
I != E; ++I) {
104-
// Avoid weird non-substring cases like phantom "." components.
105-
// In practice, Component is a substring for all "normal" ancestors.
106-
if (I->end() < Parent.begin() || I->end() > Parent.end())
107-
continue;
108-
Ancestors.emplace_back(Parent.begin(), I->end() - Parent.begin());
102+
for (auto Ancestor = absoluteParent(P.Path); !Ancestor.empty();
103+
Ancestor = absoluteParent(Ancestor)) {
104+
Ancestors.emplace_back(Ancestor);
109105
}
110106
// Ensure corresponding cache entries exist in the map.
111107
llvm::SmallVector<FileConfigCache *, 8> Caches;
@@ -127,7 +123,7 @@ Provider::fromAncestorRelativeYAMLFiles(llvm::StringRef RelPath,
127123
// Finally query each individual file.
128124
// This will take a (per-file) lock for each file that actually exists.
129125
std::vector<CompiledFragment> Result;
130-
for (FileConfigCache *Cache : Caches)
126+
for (FileConfigCache *Cache : llvm::reverse(Caches))
131127
Cache->get(FS, DC, P.FreshTime, Result);
132128
return Result;
133129
};

clang-tools-extra/clangd/GlobalCompilationDatabase.cpp

-15
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,6 @@ namespace clang {
4343
namespace clangd {
4444
namespace {
4545

46-
// Variant of parent_path that operates only on absolute paths.
47-
PathRef absoluteParent(PathRef Path) {
48-
assert(llvm::sys::path::is_absolute(Path));
49-
#if defined(_WIN32)
50-
// llvm::sys says "C:\" is absolute, and its parent is "C:" which is relative.
51-
// This unhelpful behavior seems to have been inherited from boost.
52-
if (llvm::sys::path::relative_path(Path).empty()) {
53-
return PathRef();
54-
}
55-
#endif
56-
PathRef Result = llvm::sys::path::parent_path(Path);
57-
assert(Result.empty() || llvm::sys::path::is_absolute(Result));
58-
return Result;
59-
}
60-
6146
// Runs the given action on all parent directories of filename, starting from
6247
// deepest directory and going up to root. Stops whenever action succeeds.
6348
void actOnAllParentDirectories(PathRef FileName,

clang-tools-extra/clangd/TidyProvider.cpp

+3-13
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "Config.h"
1212
#include "support/FileCache.h"
1313
#include "support/Logger.h"
14+
#include "support/Path.h"
1415
#include "support/ThreadsafeFS.h"
1516
#include "llvm/ADT/STLExtras.h"
1617
#include "llvm/ADT/SmallString.h"
@@ -102,23 +103,12 @@ class DotClangTidyTree {
102103

103104
// Compute absolute paths to all ancestors (substrings of P.Path).
104105
// Ensure cache entries for each ancestor exist in the map.
105-
llvm::StringRef Parent = path::parent_path(AbsPath);
106106
llvm::SmallVector<DotClangTidyCache *> Caches;
107107
{
108108
std::lock_guard<std::mutex> Lock(Mu);
109-
for (auto I = path::rbegin(Parent), E = path::rend(Parent); I != E; ++I) {
110-
assert(I->end() >= Parent.begin() && I->end() <= Parent.end() &&
111-
"Canonical path components should be substrings");
112-
llvm::StringRef Ancestor(Parent.begin(), I->end() - Parent.begin());
113-
#ifdef _WIN32
114-
// C:\ is an ancestor, but skip its (relative!) parent C:.
115-
if (Ancestor.size() == 2 && Ancestor.back() == ':')
116-
continue;
117-
#endif
118-
assert(path::is_absolute(Ancestor));
119-
109+
for (auto Ancestor = absoluteParent(AbsPath); !Ancestor.empty();
110+
Ancestor = absoluteParent(Ancestor)) {
120111
auto It = Cache.find(Ancestor);
121-
122112
// Assemble the actual config file path only if needed.
123113
if (It == Cache.end()) {
124114
llvm::SmallString<256> ConfigPath = Ancestor;

clang-tools-extra/clangd/support/Path.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ std::string maybeCaseFoldPath(PathRef Path) { return Path.str(); }
1919
bool pathEqual(PathRef A, PathRef B) { return A == B; }
2020
#endif // CLANGD_PATH_CASE_INSENSITIVE
2121

22+
PathRef absoluteParent(PathRef Path) {
23+
assert(llvm::sys::path::is_absolute(Path));
24+
#if defined(_WIN32)
25+
// llvm::sys says "C:\" is absolute, and its parent is "C:" which is relative.
26+
// This unhelpful behavior seems to have been inherited from boost.
27+
if (llvm::sys::path::relative_path(Path).empty()) {
28+
return PathRef();
29+
}
30+
#endif
31+
PathRef Result = llvm::sys::path::parent_path(Path);
32+
assert(Result.empty() || llvm::sys::path::is_absolute(Result));
33+
return Result;
34+
}
35+
2236
bool pathStartsWith(PathRef Ancestor, PathRef Path,
2337
llvm::sys::path::Style Style) {
2438
assert(llvm::sys::path::is_absolute(Ancestor) &&

clang-tools-extra/clangd/support/Path.h

+4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ bool pathEqual(PathRef, PathRef);
4040
bool pathStartsWith(
4141
PathRef Ancestor, PathRef Path,
4242
llvm::sys::path::Style Style = llvm::sys::path::Style::native);
43+
44+
/// Variant of parent_path that operates only on absolute paths.
45+
/// Unlike parent_path doesn't consider C: a parent of C:\.
46+
PathRef absoluteParent(PathRef Path);
4347
} // namespace clangd
4448
} // namespace clang
4549

0 commit comments

Comments
 (0)