From b60736ec1405bb0a8dd40989f67ef4c93da068ab Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 16 Feb 2021 21:13:02 +0100 Subject: Vendor import of llvm-project main 8e464dd76bef, the last commit before the upstream release/12.x branch was created. --- llvm/lib/Support/VirtualFileSystem.cpp | 158 ++++++++++++++++++++++++++------- 1 file changed, 124 insertions(+), 34 deletions(-) (limited to 'llvm/lib/Support/VirtualFileSystem.cpp') diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp index 5b757c9ea80d..05332b00bd1f 100644 --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -792,14 +792,12 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, } bool InMemoryFileSystem::addFileNoOwn(const Twine &P, time_t ModificationTime, - llvm::MemoryBuffer *Buffer, + const llvm::MemoryBufferRef &Buffer, Optional User, Optional Group, Optional Type, Optional Perms) { - return addFile(P, ModificationTime, - llvm::MemoryBuffer::getMemBuffer( - Buffer->getBuffer(), Buffer->getBufferIdentifier()), + return addFile(P, ModificationTime, llvm::MemoryBuffer::getMemBuffer(Buffer), std::move(User), std::move(Group), std::move(Type), std::move(Perms)); } @@ -1018,7 +1016,6 @@ RedirectingFileSystem::RedirectingFileSystem(IntrusiveRefCntPtr FS) if (auto ExternalWorkingDirectory = ExternalFS->getCurrentWorkingDirectory()) { WorkingDirectory = *ExternalWorkingDirectory; - ExternalFSValidWD = true; } } @@ -1077,12 +1074,6 @@ RedirectingFileSystem::setCurrentWorkingDirectory(const Twine &Path) { if (!exists(Path)) return errc::no_such_file_or_directory; - // Always change the external FS but ignore its result. - if (ExternalFS) { - auto EC = ExternalFS->setCurrentWorkingDirectory(Path); - ExternalFSValidWD = !static_cast(EC); - } - SmallString<128> AbsolutePath; Path.toVector(AbsolutePath); if (std::error_code EC = makeAbsolute(AbsolutePath)) @@ -1091,8 +1082,14 @@ RedirectingFileSystem::setCurrentWorkingDirectory(const Twine &Path) { return {}; } -std::error_code RedirectingFileSystem::isLocal(const Twine &Path, +std::error_code RedirectingFileSystem::isLocal(const Twine &Path_, bool &Result) { + SmallString<256> Path; + Path_.toVector(Path); + + if (std::error_code EC = makeCanonical(Path)) + return {}; + return ExternalFS->isLocal(Path, Result); } @@ -1127,14 +1124,21 @@ std::error_code RedirectingFileSystem::makeAbsolute(SmallVectorImpl &Path) directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir, std::error_code &EC) { - ErrorOr E = lookupPath(Dir); + SmallString<256> Path; + Dir.toVector(Path); + + EC = makeCanonical(Path); + if (EC) + return {}; + + ErrorOr E = lookupPath(Path); if (!E) { EC = E.getError(); if (shouldUseExternalFS() && EC == errc::no_such_file_or_directory) - return ExternalFS->dir_begin(Dir, EC); + return ExternalFS->dir_begin(Path, EC); return {}; } - ErrorOr S = status(Dir, *E); + ErrorOr S = status(Path, *E); if (!S) { EC = S.getError(); return {}; @@ -1147,7 +1151,7 @@ directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir, auto *D = cast(*E); return directory_iterator(std::make_shared( - Dir, D->contents_begin(), D->contents_end(), + Path, D->contents_begin(), D->contents_end(), /*IterateExternalFS=*/shouldUseExternalFS(), *ExternalFS, EC)); } @@ -1159,6 +1163,17 @@ StringRef RedirectingFileSystem::getExternalContentsPrefixDir() const { return ExternalContentsPrefixDir; } +void RedirectingFileSystem::setFallthrough(bool Fallthrough) { + IsFallthrough = Fallthrough; +} + +std::vector RedirectingFileSystem::getRoots() const { + std::vector R; + for (const auto &Root : Roots) + R.push_back(Root->getName()); + return R; +} + void RedirectingFileSystem::dump(raw_ostream &OS) const { for (const auto &Root : Roots) dumpEntry(OS, Root.get()); @@ -1263,7 +1278,8 @@ class llvm::vfs::RedirectingFileSystemParser { return true; } - RedirectingFileSystem::Entry * +public: + static RedirectingFileSystem::Entry * lookupOrCreateEntry(RedirectingFileSystem *FS, StringRef Name, RedirectingFileSystem::Entry *ParentEntry = nullptr) { if (!ParentEntry) { // Look for a existent root @@ -1305,6 +1321,7 @@ class llvm::vfs::RedirectingFileSystemParser { return DE->getLastContent(); } +private: void uniqueOverlayTree(RedirectingFileSystem *FS, RedirectingFileSystem::Entry *SrcE, RedirectingFileSystem::Entry *NewParentE = nullptr) { @@ -1630,7 +1647,7 @@ public: } }; -RedirectingFileSystem * +std::unique_ptr RedirectingFileSystem::create(std::unique_ptr Buffer, SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath, void *DiagContext, @@ -1670,25 +1687,80 @@ RedirectingFileSystem::create(std::unique_ptr Buffer, if (!P.parse(Root, FS.get())) return nullptr; - return FS.release(); + return FS; } -ErrorOr -RedirectingFileSystem::lookupPath(const Twine &Path_) const { - SmallString<256> Path; - Path_.toVector(Path); +std::unique_ptr RedirectingFileSystem::create( + ArrayRef> RemappedFiles, + bool UseExternalNames, FileSystem &ExternalFS) { + std::unique_ptr FS( + new RedirectingFileSystem(&ExternalFS)); + FS->UseExternalNames = UseExternalNames; + + StringMap Entries; + + for (auto &Mapping : llvm::reverse(RemappedFiles)) { + SmallString<128> From = StringRef(Mapping.first); + SmallString<128> To = StringRef(Mapping.second); + { + auto EC = ExternalFS.makeAbsolute(From); + (void)EC; + assert(!EC && "Could not make absolute path"); + } - // Handle relative paths + // Check if we've already mapped this file. The first one we see (in the + // reverse iteration) wins. + RedirectingFileSystem::Entry *&ToEntry = Entries[From]; + if (ToEntry) + continue; + + // Add parent directories. + RedirectingFileSystem::Entry *Parent = nullptr; + StringRef FromDirectory = llvm::sys::path::parent_path(From); + for (auto I = llvm::sys::path::begin(FromDirectory), + E = llvm::sys::path::end(FromDirectory); + I != E; ++I) { + Parent = RedirectingFileSystemParser::lookupOrCreateEntry(FS.get(), *I, + Parent); + } + assert(Parent && "File without a directory?"); + { + auto EC = ExternalFS.makeAbsolute(To); + (void)EC; + assert(!EC && "Could not make absolute path"); + } + + // Add the file. + auto NewFile = + std::make_unique( + llvm::sys::path::filename(From), To, + UseExternalNames + ? RedirectingFileSystem::RedirectingFileEntry::NK_External + : RedirectingFileSystem::RedirectingFileEntry::NK_Virtual); + ToEntry = NewFile.get(); + cast(Parent)->addContent( + std::move(NewFile)); + } + + return FS; +} + +std::error_code +RedirectingFileSystem::makeCanonical(SmallVectorImpl &Path) const { if (std::error_code EC = makeAbsolute(Path)) return EC; - // Canonicalize path by removing ".", "..", "./", components. This is - // a VFS request, do not bother about symlinks in the path components - // but canonicalize in order to perform the correct entry search. - Path = canonicalize(Path); - if (Path.empty()) + llvm::SmallString<256> CanonicalPath = + canonicalize(StringRef(Path.data(), Path.size())); + if (CanonicalPath.empty()) return make_error_code(llvm::errc::invalid_argument); + Path.assign(CanonicalPath.begin(), CanonicalPath.end()); + return {}; +} + +ErrorOr +RedirectingFileSystem::lookupPath(StringRef Path) const { sys::path::const_iterator Start = sys::path::begin(Path); sys::path::const_iterator End = sys::path::end(Path); for (const auto &Root : Roots) { @@ -1763,7 +1835,13 @@ ErrorOr RedirectingFileSystem::status(const Twine &Path, } } -ErrorOr RedirectingFileSystem::status(const Twine &Path) { +ErrorOr RedirectingFileSystem::status(const Twine &Path_) { + SmallString<256> Path; + Path_.toVector(Path); + + if (std::error_code EC = makeCanonical(Path)) + return EC; + ErrorOr Result = lookupPath(Path); if (!Result) { if (shouldUseExternalFS() && @@ -1801,7 +1879,13 @@ public: } // namespace ErrorOr> -RedirectingFileSystem::openFileForRead(const Twine &Path) { +RedirectingFileSystem::openFileForRead(const Twine &Path_) { + SmallString<256> Path; + Path_.toVector(Path); + + if (std::error_code EC = makeCanonical(Path)) + return EC; + ErrorOr E = lookupPath(Path); if (!E) { if (shouldUseExternalFS() && @@ -1831,8 +1915,14 @@ RedirectingFileSystem::openFileForRead(const Twine &Path) { } std::error_code -RedirectingFileSystem::getRealPath(const Twine &Path, +RedirectingFileSystem::getRealPath(const Twine &Path_, SmallVectorImpl &Output) const { + SmallString<256> Path; + Path_.toVector(Path); + + if (std::error_code EC = makeCanonical(Path)) + return EC; + ErrorOr Result = lookupPath(Path); if (!Result) { if (shouldUseExternalFS() && @@ -1852,7 +1942,7 @@ RedirectingFileSystem::getRealPath(const Twine &Path, : llvm::errc::invalid_argument; } -IntrusiveRefCntPtr +std::unique_ptr vfs::getVFSFromYAML(std::unique_ptr Buffer, SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath, void *DiagContext, @@ -1893,7 +1983,7 @@ void vfs::collectVFSFromYAML(std::unique_ptr Buffer, SmallVectorImpl &CollectedEntries, void *DiagContext, IntrusiveRefCntPtr ExternalFS) { - RedirectingFileSystem *VFS = RedirectingFileSystem::create( + std::unique_ptr VFS = RedirectingFileSystem::create( std::move(Buffer), DiagHandler, YAMLFilePath, DiagContext, std::move(ExternalFS)); ErrorOr RootE = VFS->lookupPath("/"); -- cgit v1.2.3