mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-02 18:58:15 +00:00
[clangd] Expose absoluteParent helper
Will be used in other components that need ancestor traversal. Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D96123
This commit is contained in:
parent
c1664c5a27
commit
6329ce75da
@ -10,8 +10,10 @@
|
||||
#include "Config.h"
|
||||
#include "ConfigFragment.h"
|
||||
#include "support/FileCache.h"
|
||||
#include "support/Path.h"
|
||||
#include "support/ThreadsafeFS.h"
|
||||
#include "support/Trace.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/ScopeExit.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
@ -96,16 +98,10 @@ Provider::fromAncestorRelativeYAMLFiles(llvm::StringRef RelPath,
|
||||
return {};
|
||||
|
||||
// Compute absolute paths to all ancestors (substrings of P.Path).
|
||||
llvm::StringRef Parent = path::parent_path(P.Path);
|
||||
llvm::SmallVector<llvm::StringRef, 8> Ancestors;
|
||||
for (auto I = path::begin(Parent, path::Style::posix),
|
||||
E = path::end(Parent);
|
||||
I != E; ++I) {
|
||||
// Avoid weird non-substring cases like phantom "." components.
|
||||
// In practice, Component is a substring for all "normal" ancestors.
|
||||
if (I->end() < Parent.begin() || I->end() > Parent.end())
|
||||
continue;
|
||||
Ancestors.emplace_back(Parent.begin(), I->end() - Parent.begin());
|
||||
for (auto Ancestor = absoluteParent(P.Path); !Ancestor.empty();
|
||||
Ancestor = absoluteParent(Ancestor)) {
|
||||
Ancestors.emplace_back(Ancestor);
|
||||
}
|
||||
// Ensure corresponding cache entries exist in the map.
|
||||
llvm::SmallVector<FileConfigCache *, 8> Caches;
|
||||
@ -127,7 +123,7 @@ Provider::fromAncestorRelativeYAMLFiles(llvm::StringRef RelPath,
|
||||
// Finally query each individual file.
|
||||
// This will take a (per-file) lock for each file that actually exists.
|
||||
std::vector<CompiledFragment> Result;
|
||||
for (FileConfigCache *Cache : Caches)
|
||||
for (FileConfigCache *Cache : llvm::reverse(Caches))
|
||||
Cache->get(FS, DC, P.FreshTime, Result);
|
||||
return Result;
|
||||
};
|
||||
|
@ -43,21 +43,6 @@ 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,
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "Config.h"
|
||||
#include "support/FileCache.h"
|
||||
#include "support/Logger.h"
|
||||
#include "support/Path.h"
|
||||
#include "support/ThreadsafeFS.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
@ -102,23 +103,12 @@ public:
|
||||
|
||||
// Compute absolute paths to all ancestors (substrings of P.Path).
|
||||
// Ensure cache entries for each ancestor exist in the map.
|
||||
llvm::StringRef Parent = path::parent_path(AbsPath);
|
||||
llvm::SmallVector<DotClangTidyCache *> Caches;
|
||||
{
|
||||
std::lock_guard<std::mutex> Lock(Mu);
|
||||
for (auto I = path::rbegin(Parent), E = path::rend(Parent); I != E; ++I) {
|
||||
assert(I->end() >= Parent.begin() && I->end() <= Parent.end() &&
|
||||
"Canonical path components should be substrings");
|
||||
llvm::StringRef Ancestor(Parent.begin(), I->end() - Parent.begin());
|
||||
#ifdef _WIN32
|
||||
// C:\ is an ancestor, but skip its (relative!) parent C:.
|
||||
if (Ancestor.size() == 2 && Ancestor.back() == ':')
|
||||
continue;
|
||||
#endif
|
||||
assert(path::is_absolute(Ancestor));
|
||||
|
||||
for (auto Ancestor = absoluteParent(AbsPath); !Ancestor.empty();
|
||||
Ancestor = absoluteParent(Ancestor)) {
|
||||
auto It = Cache.find(Ancestor);
|
||||
|
||||
// Assemble the actual config file path only if needed.
|
||||
if (It == Cache.end()) {
|
||||
llvm::SmallString<256> ConfigPath = Ancestor;
|
||||
|
@ -19,6 +19,20 @@ std::string maybeCaseFoldPath(PathRef Path) { return Path.str(); }
|
||||
bool pathEqual(PathRef A, PathRef B) { return A == B; }
|
||||
#endif // CLANGD_PATH_CASE_INSENSITIVE
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool pathStartsWith(PathRef Ancestor, PathRef Path,
|
||||
llvm::sys::path::Style Style) {
|
||||
assert(llvm::sys::path::is_absolute(Ancestor) &&
|
||||
|
@ -40,6 +40,10 @@ bool pathEqual(PathRef, PathRef);
|
||||
bool pathStartsWith(
|
||||
PathRef Ancestor, PathRef Path,
|
||||
llvm::sys::path::Style Style = llvm::sys::path::Style::native);
|
||||
|
||||
/// Variant of parent_path that operates only on absolute paths.
|
||||
/// Unlike parent_path doesn't consider C: a parent of C:\.
|
||||
PathRef absoluteParent(PathRef Path);
|
||||
} // namespace clangd
|
||||
} // namespace clang
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user