diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-01-27 22:17:16 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-06-04 11:59:19 +0000 |
commit | 390adc38fc112be360bd15499e5241bf4e675b6f (patch) | |
tree | 712d68d3aa03f7aa4902ba03dcac2a56f49ae0e5 /contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp | |
parent | 8a84287b0edc66fc6dede3db770d10ff41da5464 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp | 112 |
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; } } |