From 1d5ae1026e831016fc29fd927877c86af904481f Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Wed, 23 Oct 2019 17:51:42 +0000 Subject: Vendor import of stripped llvm trunk r375505, the last commit before the upstream Subversion repository was made read-only, and the LLVM project migrated to GitHub: https://llvm.org/svn/llvm-project/llvm/trunk@375505 --- lib/Support/VirtualFileSystem.cpp | 102 +++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 39 deletions(-) (limited to 'lib/Support/VirtualFileSystem.cpp') diff --git a/lib/Support/VirtualFileSystem.cpp b/lib/Support/VirtualFileSystem.cpp index 5d3480e97148d..c390cb1b22275 100644 --- a/lib/Support/VirtualFileSystem.cpp +++ b/lib/Support/VirtualFileSystem.cpp @@ -176,9 +176,9 @@ class RealFile : public File { Status S; std::string RealName; - RealFile(file_t FD, StringRef NewName, StringRef NewRealPathName) - : FD(FD), S(NewName, {}, {}, {}, {}, {}, - llvm::sys::fs::file_type::status_error, {}), + RealFile(file_t RawFD, StringRef NewName, StringRef NewRealPathName) + : FD(RawFD), S(NewName, {}, {}, {}, {}, {}, + llvm::sys::fs::file_type::status_error, {}), RealName(NewRealPathName.str()) { assert(FD != kInvalidFile && "Invalid or inactive file descriptor"); } @@ -349,7 +349,7 @@ IntrusiveRefCntPtr vfs::getRealFileSystem() { } std::unique_ptr vfs::createPhysicalFileSystem() { - return llvm::make_unique(false); + return std::make_unique(false); } namespace { @@ -754,7 +754,7 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, ResolvedUser, ResolvedGroup, 0, sys::fs::file_type::directory_file, NewDirectoryPerms); Dir = cast(Dir->addChild( - Name, llvm::make_unique(std::move(Stat)))); + Name, std::make_unique(std::move(Stat)))); continue; } @@ -989,6 +989,16 @@ std::error_code InMemoryFileSystem::isLocal(const Twine &Path, bool &Result) { // RedirectingFileSystem implementation //===-----------------------------------------------------------------------===/ +RedirectingFileSystem::RedirectingFileSystem(IntrusiveRefCntPtr FS) + : ExternalFS(std::move(FS)) { + if (ExternalFS) + if (auto ExternalWorkingDirectory = + ExternalFS->getCurrentWorkingDirectory()) { + WorkingDirectory = *ExternalWorkingDirectory; + ExternalFSValidWD = true; + } +} + // FIXME: reuse implementation common with OverlayFSDirIterImpl as these // iterators are conceptually similar. class llvm::vfs::VFSFromYamlDirIterImpl @@ -1035,12 +1045,27 @@ public: llvm::ErrorOr RedirectingFileSystem::getCurrentWorkingDirectory() const { - return ExternalFS->getCurrentWorkingDirectory(); + return WorkingDirectory; } std::error_code RedirectingFileSystem::setCurrentWorkingDirectory(const Twine &Path) { - return ExternalFS->setCurrentWorkingDirectory(Path); + // Don't change the working directory if the path doesn't exist. + 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)) + return EC; + WorkingDirectory = AbsolutePath.str(); + return {}; } std::error_code RedirectingFileSystem::isLocal(const Twine &Path, @@ -1053,7 +1078,7 @@ directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir, ErrorOr E = lookupPath(Dir); if (!E) { EC = E.getError(); - if (IsFallthrough && EC == errc::no_such_file_or_directory) + if (shouldUseExternalFS() && EC == errc::no_such_file_or_directory) return ExternalFS->dir_begin(Dir, EC); return {}; } @@ -1071,7 +1096,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(), - /*IterateExternalFS=*/IsFallthrough, *ExternalFS, EC)); + /*IterateExternalFS=*/shouldUseExternalFS(), *ExternalFS, EC)); } void RedirectingFileSystem::setExternalContentsPrefixDir(StringRef PrefixDir) { @@ -1082,20 +1107,19 @@ StringRef RedirectingFileSystem::getExternalContentsPrefixDir() const { return ExternalContentsPrefixDir; } -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD void RedirectingFileSystem::dump() const { +void RedirectingFileSystem::dump(raw_ostream &OS) const { for (const auto &Root : Roots) - dumpEntry(Root.get()); + dumpEntry(OS, Root.get()); } -LLVM_DUMP_METHOD void -RedirectingFileSystem::dumpEntry(RedirectingFileSystem::Entry *E, - int NumSpaces) const { +void RedirectingFileSystem::dumpEntry(raw_ostream &OS, + RedirectingFileSystem::Entry *E, + int NumSpaces) const { StringRef Name = E->getName(); for (int i = 0, e = NumSpaces; i < e; ++i) - dbgs() << " "; - dbgs() << "'" << Name.str().c_str() << "'" - << "\n"; + OS << " "; + OS << "'" << Name.str().c_str() << "'" + << "\n"; if (E->getKind() == RedirectingFileSystem::EK_Directory) { auto *DE = dyn_cast(E); @@ -1103,9 +1127,12 @@ RedirectingFileSystem::dumpEntry(RedirectingFileSystem::Entry *E, for (std::unique_ptr &SubEntry : llvm::make_range(DE->contents_begin(), DE->contents_end())) - dumpEntry(SubEntry.get(), NumSpaces + 2); + dumpEntry(OS, SubEntry.get(), NumSpaces + 2); } } + +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +LLVM_DUMP_METHOD void RedirectingFileSystem::dump() const { dump(dbgs()); } #endif /// A helper class to hold the common YAML parsing state. @@ -1209,7 +1236,7 @@ class llvm::vfs::RedirectingFileSystemParser { // ... or create a new one std::unique_ptr E = - llvm::make_unique( + std::make_unique( Name, Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), 0, 0, 0, file_type::directory_file, sys::fs::all_all)); @@ -1221,7 +1248,7 @@ class llvm::vfs::RedirectingFileSystemParser { } auto *DE = - dyn_cast(ParentEntry); + cast(ParentEntry); DE->addContent(std::move(E)); return DE->getLastContent(); } @@ -1232,9 +1259,7 @@ class llvm::vfs::RedirectingFileSystemParser { StringRef Name = SrcE->getName(); switch (SrcE->getKind()) { case RedirectingFileSystem::EK_Directory: { - auto *DE = - dyn_cast(SrcE); - assert(DE && "Must be a directory"); + auto *DE = cast(SrcE); // Empty directories could be present in the YAML as a way to // describe a file for a current directory after some of its subdir // is parsed. This only leads to redundant walks, ignore it. @@ -1246,13 +1271,12 @@ class llvm::vfs::RedirectingFileSystemParser { break; } case RedirectingFileSystem::EK_File: { - auto *FE = dyn_cast(SrcE); - assert(FE && "Must be a file"); assert(NewParentE && "Parent entry must exist"); - auto *DE = dyn_cast( - NewParentE); + auto *FE = cast(SrcE); + auto *DE = + cast(NewParentE); DE->addContent( - llvm::make_unique( + std::make_unique( Name, FE->getExternalContentsPath(), FE->getUseName())); break; } @@ -1423,12 +1447,12 @@ class llvm::vfs::RedirectingFileSystemParser { std::unique_ptr Result; switch (Kind) { case RedirectingFileSystem::EK_File: - Result = llvm::make_unique( + Result = std::make_unique( LastComponent, std::move(ExternalContentsPath), UseExternalName); break; case RedirectingFileSystem::EK_Directory: Result = - llvm::make_unique( + std::make_unique( LastComponent, std::move(EntryArrayContents), Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), 0, 0, 0, @@ -1447,7 +1471,7 @@ class llvm::vfs::RedirectingFileSystemParser { std::vector> Entries; Entries.push_back(std::move(Result)); Result = - llvm::make_unique( + std::make_unique( *I, std::move(Entries), Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), 0, 0, 0, @@ -1573,7 +1597,7 @@ RedirectingFileSystem::create(std::unique_ptr Buffer, RedirectingFileSystemParser P(Stream); std::unique_ptr FS( - new RedirectingFileSystem(std::move(ExternalFS))); + new RedirectingFileSystem(ExternalFS)); if (!YAMLFilePath.empty()) { // Use the YAML path from -ivfsoverlay to compute the dir to be prefixed @@ -1702,7 +1726,7 @@ ErrorOr RedirectingFileSystem::status(const Twine &Path, ErrorOr RedirectingFileSystem::status(const Twine &Path) { ErrorOr Result = lookupPath(Path); if (!Result) { - if (IsFallthrough && + if (shouldUseExternalFS() && Result.getError() == llvm::errc::no_such_file_or_directory) { return ExternalFS->status(Path); } @@ -1740,7 +1764,7 @@ ErrorOr> RedirectingFileSystem::openFileForRead(const Twine &Path) { ErrorOr E = lookupPath(Path); if (!E) { - if (IsFallthrough && + if (shouldUseExternalFS() && E.getError() == llvm::errc::no_such_file_or_directory) { return ExternalFS->openFileForRead(Path); } @@ -1763,7 +1787,7 @@ RedirectingFileSystem::openFileForRead(const Twine &Path) { Status S = getRedirectedFileStatus(Path, F->useExternalName(UseExternalNames), *ExternalStatus); return std::unique_ptr( - llvm::make_unique(std::move(*Result), S)); + std::make_unique(std::move(*Result), S)); } std::error_code @@ -1771,7 +1795,7 @@ RedirectingFileSystem::getRealPath(const Twine &Path, SmallVectorImpl &Output) const { ErrorOr Result = lookupPath(Path); if (!Result) { - if (IsFallthrough && + if (shouldUseExternalFS() && Result.getError() == llvm::errc::no_such_file_or_directory) { return ExternalFS->getRealPath(Path, Output); } @@ -1784,8 +1808,8 @@ RedirectingFileSystem::getRealPath(const Twine &Path, } // Even if there is a directory entry, fall back to ExternalFS if allowed, // because directories don't have a single external contents path. - return IsFallthrough ? ExternalFS->getRealPath(Path, Output) - : llvm::errc::invalid_argument; + return shouldUseExternalFS() ? ExternalFS->getRealPath(Path, Output) + : llvm::errc::invalid_argument; } IntrusiveRefCntPtr -- cgit v1.2.3