aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/VirtualFileSystem.cpp
diff options
context:
space:
mode:
authorKeith Smiley <keithbsmiley@gmail.com>2021-11-13 09:34:30 -0800
committerKeith Smiley <keithbsmiley@gmail.com>2021-11-13 09:34:44 -0800
commitc972175649f4bb50d40d911659a04d5620ce6fe0 (patch)
tree3ebb0316368673a710028b8dacfbb68314127b47 /llvm/lib/Support/VirtualFileSystem.cpp
parentc3a3e65ecc082542080376e917d9c57d22901f6b (diff)
downloadllvm-c972175649f4bb50d40d911659a04d5620ce6fe0.zip
llvm-c972175649f4bb50d40d911659a04d5620ce6fe0.tar.gz
llvm-c972175649f4bb50d40d911659a04d5620ce6fe0.tar.bz2
[VFS] Use original path when falling back to external FS
This is a follow up to 0be9ca7c0f9a733f846bb6bc4e8e36d46b518162 to make paths in the case of falling back to the external file system use the original format, preserving relative paths, and allow the external filesystem to canonicalize them if needed. Reviewed By: dexonsmith Differential Revision: https://reviews.llvm.org/D109128
Diffstat (limited to 'llvm/lib/Support/VirtualFileSystem.cpp')
-rw-r--r--llvm/lib/Support/VirtualFileSystem.cpp107
1 files changed, 80 insertions, 27 deletions
diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp
index a4abfe1..d0ba311 100644
--- a/llvm/lib/Support/VirtualFileSystem.cpp
+++ b/llvm/lib/Support/VirtualFileSystem.cpp
@@ -194,6 +194,7 @@ public:
bool RequiresNullTerminator,
bool IsVolatile) override;
std::error_code close() override;
+ void setPath(const Twine &Path) override;
};
} // namespace
@@ -229,6 +230,12 @@ std::error_code RealFile::close() {
return EC;
}
+void RealFile::setPath(const Twine &Path) {
+ RealName = Path.str();
+ if (auto Status = status())
+ S = Status.get().copyWithNewName(Status.get(), Path);
+}
+
namespace {
/// A file system according to your operating system.
@@ -639,6 +646,8 @@ public:
}
std::error_code close() override { return {}; }
+
+ void setPath(const Twine &Path) override { RequestedName = Path.str(); }
};
} // namespace
@@ -1244,7 +1253,7 @@ directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir,
}
// Use status to make sure the path exists and refers to a directory.
- ErrorOr<Status> S = status(Path, *Result);
+ ErrorOr<Status> S = status(Path, Dir, *Result);
if (!S) {
if (shouldFallBackToExternalFS(S.getError(), Result->E))
return ExternalFS->dir_begin(Dir, EC);
@@ -1971,47 +1980,68 @@ RedirectingFileSystem::lookupPathImpl(
return make_error_code(llvm::errc::no_such_file_or_directory);
}
-static Status getRedirectedFileStatus(const Twine &Path, bool UseExternalNames,
+static Status getRedirectedFileStatus(const Twine &OriginalPath,
+ bool UseExternalNames,
Status ExternalStatus) {
Status S = ExternalStatus;
if (!UseExternalNames)
- S = Status::copyWithNewName(S, Path);
+ S = Status::copyWithNewName(S, OriginalPath);
S.IsVFSMapped = true;
return S;
}
ErrorOr<Status> RedirectingFileSystem::status(
- const Twine &Path, const RedirectingFileSystem::LookupResult &Result) {
+ const Twine &CanonicalPath, const Twine &OriginalPath,
+ const RedirectingFileSystem::LookupResult &Result) {
if (Optional<StringRef> ExtRedirect = Result.getExternalRedirect()) {
- ErrorOr<Status> S = ExternalFS->status(*ExtRedirect);
+ SmallString<256> CanonicalRemappedPath((*ExtRedirect).str());
+ if (std::error_code EC = makeCanonical(CanonicalRemappedPath))
+ return EC;
+
+ ErrorOr<Status> S = ExternalFS->status(CanonicalRemappedPath);
if (!S)
return S;
+ S = Status::copyWithNewName(*S, *ExtRedirect);
auto *RE = cast<RedirectingFileSystem::RemapEntry>(Result.E);
- return getRedirectedFileStatus(Path, RE->useExternalName(UseExternalNames),
- *S);
+ return getRedirectedFileStatus(OriginalPath,
+ RE->useExternalName(UseExternalNames), *S);
}
auto *DE = cast<RedirectingFileSystem::DirectoryEntry>(Result.E);
- return Status::copyWithNewName(DE->getStatus(), Path);
+ return Status::copyWithNewName(DE->getStatus(), CanonicalPath);
}
-ErrorOr<Status> RedirectingFileSystem::status(const Twine &Path_) {
- SmallString<256> Path;
- Path_.toVector(Path);
+ErrorOr<Status>
+RedirectingFileSystem::getExternalStatus(const Twine &CanonicalPath,
+ const Twine &OriginalPath) const {
+ if (auto Result = ExternalFS->status(CanonicalPath)) {
+ return Result.get().copyWithNewName(Result.get(), OriginalPath);
+ } else {
+ return Result.getError();
+ }
+}
- if (std::error_code EC = makeCanonical(Path))
+ErrorOr<Status> RedirectingFileSystem::status(const Twine &OriginalPath) {
+ SmallString<256> CanonicalPath;
+ OriginalPath.toVector(CanonicalPath);
+
+ if (std::error_code EC = makeCanonical(CanonicalPath))
return EC;
- ErrorOr<RedirectingFileSystem::LookupResult> Result = lookupPath(Path);
+ ErrorOr<RedirectingFileSystem::LookupResult> Result =
+ lookupPath(CanonicalPath);
if (!Result) {
- if (shouldFallBackToExternalFS(Result.getError()))
- return ExternalFS->status(Path);
+ if (shouldFallBackToExternalFS(Result.getError())) {
+ return getExternalStatus(CanonicalPath, OriginalPath);
+ }
return Result.getError();
}
- ErrorOr<Status> S = status(Path, *Result);
- if (!S && shouldFallBackToExternalFS(S.getError(), Result->E))
- S = ExternalFS->status(Path);
+ ErrorOr<Status> S = status(CanonicalPath, OriginalPath, *Result);
+ if (!S && shouldFallBackToExternalFS(S.getError(), Result->E)) {
+ return getExternalStatus(CanonicalPath, OriginalPath);
+ }
+
return S;
}
@@ -2036,22 +2066,39 @@ public:
}
std::error_code close() override { return InnerFile->close(); }
+
+ void setPath(const Twine &Path) override { S = S.copyWithNewName(S, Path); }
};
} // namespace
ErrorOr<std::unique_ptr<File>>
-RedirectingFileSystem::openFileForRead(const Twine &Path_) {
- SmallString<256> Path;
- Path_.toVector(Path);
+File::getWithPath(ErrorOr<std::unique_ptr<File>> Result, const Twine &P) {
+ if (!Result)
+ return Result;
- if (std::error_code EC = makeCanonical(Path))
+ auto F = std::move(*Result);
+ auto Name = F->getName();
+ if (Name && Name.get() != P.str())
+ F->setPath(P);
+ return F;
+}
+
+ErrorOr<std::unique_ptr<File>>
+RedirectingFileSystem::openFileForRead(const Twine &OriginalPath) {
+ SmallString<256> CanonicalPath;
+ OriginalPath.toVector(CanonicalPath);
+
+ if (std::error_code EC = makeCanonical(CanonicalPath))
return EC;
- ErrorOr<RedirectingFileSystem::LookupResult> Result = lookupPath(Path);
+ ErrorOr<RedirectingFileSystem::LookupResult> Result =
+ lookupPath(CanonicalPath);
if (!Result) {
if (shouldFallBackToExternalFS(Result.getError()))
- return ExternalFS->openFileForRead(Path);
+ return File::getWithPath(ExternalFS->openFileForRead(CanonicalPath),
+ OriginalPath);
+
return Result.getError();
}
@@ -2059,12 +2106,18 @@ RedirectingFileSystem::openFileForRead(const Twine &Path_) {
return make_error_code(llvm::errc::invalid_argument);
StringRef ExtRedirect = *Result->getExternalRedirect();
+ SmallString<256> CanonicalRemappedPath(ExtRedirect.str());
+ if (std::error_code EC = makeCanonical(CanonicalRemappedPath))
+ return EC;
+
auto *RE = cast<RedirectingFileSystem::RemapEntry>(Result->E);
- auto ExternalFile = ExternalFS->openFileForRead(ExtRedirect);
+ auto ExternalFile = File::getWithPath(
+ ExternalFS->openFileForRead(CanonicalRemappedPath), ExtRedirect);
if (!ExternalFile) {
if (shouldFallBackToExternalFS(ExternalFile.getError(), Result->E))
- return ExternalFS->openFileForRead(Path);
+ return File::getWithPath(ExternalFS->openFileForRead(CanonicalPath),
+ OriginalPath);
return ExternalFile;
}
@@ -2074,7 +2127,7 @@ RedirectingFileSystem::openFileForRead(const Twine &Path_) {
// FIXME: Update the status with the name and VFSMapped.
Status S = getRedirectedFileStatus(
- Path, RE->useExternalName(UseExternalNames), *ExternalStatus);
+ OriginalPath, RE->useExternalName(UseExternalNames), *ExternalStatus);
return std::unique_ptr<File>(
std::make_unique<FileWithFixedStatus>(std::move(*ExternalFile), S));
}