aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-01-27 22:17:16 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-06-04 11:59:19 +0000
commit390adc38fc112be360bd15499e5241bf4e675b6f (patch)
tree712d68d3aa03f7aa4902ba03dcac2a56f49ae0e5 /contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp
parent8a84287b0edc66fc6dede3db770d10ff41da5464 (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp112
1 files changed, 62 insertions, 50 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp b/contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp
index bec4e8dbe06c..f15e301874c4 100644
--- a/contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp
+++ b/contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp
@@ -35,7 +35,6 @@
#include "llvm/Support/FileSystem/UniqueID.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
@@ -46,9 +45,7 @@
#include <cstdint>
#include <iterator>
#include <limits>
-#include <map>
#include <memory>
-#include <mutex>
#include <string>
#include <system_error>
#include <utility>
@@ -574,6 +571,11 @@ public:
}
virtual ~InMemoryNode() = default;
+ /// Return the \p Status for this node. \p RequestedName should be the name
+ /// through which the caller referred to this node. It will override
+ /// \p Status::Name in the return value, to mimic the behavior of \p RealFile.
+ virtual Status getStatus(const Twine &RequestedName) const = 0;
+
/// Get the filename of this node (the name without the directory part).
StringRef getFileName() const { return FileName; }
InMemoryNodeKind getKind() const { return Kind; }
@@ -589,10 +591,7 @@ public:
: InMemoryNode(Stat.getName(), IME_File), Stat(std::move(Stat)),
Buffer(std::move(Buffer)) {}
- /// Return the \p Status for this node. \p RequestedName should be the name
- /// through which the caller referred to this node. It will override
- /// \p Status::Name in the return value, to mimic the behavior of \p RealFile.
- Status getStatus(const Twine &RequestedName) const {
+ Status getStatus(const Twine &RequestedName) const override {
return Status::copyWithNewName(Stat, RequestedName);
}
llvm::MemoryBuffer *getBuffer() const { return Buffer.get(); }
@@ -616,6 +615,10 @@ public:
: InMemoryNode(Path, IME_HardLink), ResolvedFile(ResolvedFile) {}
const InMemoryFile &getResolvedFile() const { return ResolvedFile; }
+ Status getStatus(const Twine &RequestedName) const override {
+ return ResolvedFile.getStatus(RequestedName);
+ }
+
std::string toString(unsigned Indent) const override {
return std::string(Indent, ' ') + "HardLink to -> " +
ResolvedFile.toString(0);
@@ -668,7 +671,7 @@ public:
/// Return the \p Status for this node. \p RequestedName should be the name
/// through which the caller referred to this node. It will override
/// \p Status::Name in the return value, to mimic the behavior of \p RealFile.
- Status getStatus(const Twine &RequestedName) const {
+ Status getStatus(const Twine &RequestedName) const override {
return Status::copyWithNewName(Stat, RequestedName);
}
@@ -704,17 +707,6 @@ public:
}
};
-namespace {
-Status getNodeStatus(const InMemoryNode *Node, const Twine &RequestedName) {
- if (auto Dir = dyn_cast<detail::InMemoryDirectory>(Node))
- return Dir->getStatus(RequestedName);
- if (auto File = dyn_cast<detail::InMemoryFile>(Node))
- return File->getStatus(RequestedName);
- if (auto Link = dyn_cast<detail::InMemoryHardLink>(Node))
- return Link->getResolvedFile().getStatus(RequestedName);
- llvm_unreachable("Unknown node type");
-}
-} // namespace
} // namespace detail
// The UniqueID of in-memory files is derived from path and content.
@@ -734,6 +726,16 @@ static sys::fs::UniqueID getDirectoryID(sys::fs::UniqueID Parent,
return getUniqueID(llvm::hash_combine(Parent.getFile(), Name));
}
+Status detail::NewInMemoryNodeInfo::makeStatus() const {
+ UniqueID UID =
+ (Type == sys::fs::file_type::directory_file)
+ ? getDirectoryID(DirUID, Name)
+ : getFileID(DirUID, Name, Buffer ? Buffer->getBuffer() : "");
+
+ return Status(Path, UID, llvm::sys::toTimePoint(ModificationTime), User,
+ Group, Buffer ? Buffer->getBufferSize() : 0, Type, Perms);
+}
+
InMemoryFileSystem::InMemoryFileSystem(bool UseNormalizedPaths)
: Root(new detail::InMemoryDirectory(
Status("", getDirectoryID(llvm::sys::fs::UniqueID(), ""),
@@ -754,7 +756,7 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime,
Optional<uint32_t> Group,
Optional<llvm::sys::fs::file_type> Type,
Optional<llvm::sys::fs::perms> Perms,
- const detail::InMemoryFile *HardLinkTarget) {
+ MakeNodeFn MakeNode) {
SmallString<128> Path;
P.toVector(Path);
@@ -775,7 +777,6 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime,
const auto ResolvedGroup = Group.getValueOr(0);
const auto ResolvedType = Type.getValueOr(sys::fs::file_type::regular_file);
const auto ResolvedPerms = Perms.getValueOr(sys::fs::all_all);
- assert(!(HardLinkTarget && Buffer) && "HardLink cannot have a buffer");
// Any intermediate directories we create should be accessible by
// the owner, even if Perms says otherwise for the final path.
const auto NewDirectoryPerms = ResolvedPerms | sys::fs::owner_all;
@@ -786,27 +787,10 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime,
if (!Node) {
if (I == E) {
// End of the path.
- std::unique_ptr<detail::InMemoryNode> Child;
- if (HardLinkTarget)
- Child.reset(new detail::InMemoryHardLink(P.str(), *HardLinkTarget));
- else {
- // Create a new file or directory.
- Status Stat(
- P.str(),
- (ResolvedType == sys::fs::file_type::directory_file)
- ? getDirectoryID(Dir->getUniqueID(), Name)
- : getFileID(Dir->getUniqueID(), Name, Buffer->getBuffer()),
- llvm::sys::toTimePoint(ModificationTime), ResolvedUser,
- ResolvedGroup, Buffer->getBufferSize(), ResolvedType,
- ResolvedPerms);
- if (ResolvedType == sys::fs::file_type::directory_file) {
- Child.reset(new detail::InMemoryDirectory(std::move(Stat)));
- } else {
- Child.reset(
- new detail::InMemoryFile(std::move(Stat), std::move(Buffer)));
- }
- }
- Dir->addChild(Name, std::move(Child));
+ Dir->addChild(
+ Name, MakeNode({Dir->getUniqueID(), Path, Name, ModificationTime,
+ std::move(Buffer), ResolvedUser, ResolvedGroup,
+ ResolvedType, ResolvedPerms}));
return true;
}
@@ -850,7 +834,15 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime,
Optional<llvm::sys::fs::file_type> Type,
Optional<llvm::sys::fs::perms> Perms) {
return addFile(P, ModificationTime, std::move(Buffer), User, Group, Type,
- Perms, /*HardLinkTarget=*/nullptr);
+ Perms,
+ [](detail::NewInMemoryNodeInfo NNI)
+ -> std::unique_ptr<detail::InMemoryNode> {
+ Status Stat = NNI.makeStatus();
+ if (Stat.getType() == sys::fs::file_type::directory_file)
+ return std::make_unique<detail::InMemoryDirectory>(Stat);
+ return std::make_unique<detail::InMemoryFile>(
+ Stat, std::move(NNI.Buffer));
+ });
}
bool InMemoryFileSystem::addFileNoOwn(const Twine &P, time_t ModificationTime,
@@ -861,7 +853,15 @@ bool InMemoryFileSystem::addFileNoOwn(const Twine &P, time_t ModificationTime,
Optional<llvm::sys::fs::perms> Perms) {
return addFile(P, ModificationTime, llvm::MemoryBuffer::getMemBuffer(Buffer),
std::move(User), std::move(Group), std::move(Type),
- std::move(Perms));
+ std::move(Perms),
+ [](detail::NewInMemoryNodeInfo NNI)
+ -> std::unique_ptr<detail::InMemoryNode> {
+ Status Stat = NNI.makeStatus();
+ if (Stat.getType() == sys::fs::file_type::directory_file)
+ return std::make_unique<detail::InMemoryDirectory>(Stat);
+ return std::make_unique<detail::InMemoryFile>(
+ Stat, std::move(NNI.Buffer));
+ });
}
static ErrorOr<const detail::InMemoryNode *>
@@ -916,14 +916,17 @@ bool InMemoryFileSystem::addHardLink(const Twine &FromPath,
// before. Resolved ToPath must be a File.
if (!ToNode || FromNode || !isa<detail::InMemoryFile>(*ToNode))
return false;
- return this->addFile(FromPath, 0, nullptr, None, None, None, None,
- cast<detail::InMemoryFile>(*ToNode));
+ return addFile(FromPath, 0, nullptr, None, None, None, None,
+ [&](detail::NewInMemoryNodeInfo NNI) {
+ return std::make_unique<detail::InMemoryHardLink>(
+ NNI.Path.str(), *cast<detail::InMemoryFile>(*ToNode));
+ });
}
llvm::ErrorOr<Status> InMemoryFileSystem::status(const Twine &Path) {
auto Node = lookupInMemoryNode(*this, Root.get(), Path);
if (Node)
- return detail::getNodeStatus(*Node, Path);
+ return (*Node)->getStatus(Path);
return Node.getError();
}
@@ -1649,10 +1652,19 @@ private:
sys::path::Style::windows_backslash)) {
path_style = sys::path::Style::windows_backslash;
} else {
- assert(NameValueNode && "Name presence should be checked earlier");
- error(NameValueNode,
+ // Relative VFS root entries are made absolute to the current working
+ // directory, then we can determine the path style from that.
+ auto EC = sys::fs::make_absolute(Name);
+ if (EC) {
+ assert(NameValueNode && "Name presence should be checked earlier");
+ error(
+ NameValueNode,
"entry with relative path at the root level is not discoverable");
- return nullptr;
+ return nullptr;
+ }
+ path_style = sys::path::is_absolute(Name, sys::path::Style::posix)
+ ? sys::path::Style::posix
+ : sys::path::Style::windows_backslash;
}
}