diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2020-11-11 23:03:38 -0500 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2020-12-08 17:53:30 -0800 |
commit | 75cd8d756d6e88b075fae8fe631fdbb17802bdb8 (patch) | |
tree | df4bde4ec81beb710efb58420cc24f4111f649b7 /llvm/lib/Support/VirtualFileSystem.cpp | |
parent | a22eda548b8e1f9362018dec194af0ca91b35da0 (diff) | |
download | llvm-75cd8d756d6e88b075fae8fe631fdbb17802bdb8.zip llvm-75cd8d756d6e88b075fae8fe631fdbb17802bdb8.tar.gz llvm-75cd8d756d6e88b075fae8fe631fdbb17802bdb8.tar.bz2 |
Support: Add RedirectingFileSystem::create from simple list of redirections
Add an overload of `RedirectingFileSystem::create` that builds a
redirecting filesystem off of a simple vector of string pairs. This is
intended to be used to support `clang::arcmt::FileRemapper` and
`clang::PreprocessorOptions::RemappedFiles`.
Differential Revision: https://reviews.llvm.org/D91317
Diffstat (limited to 'llvm/lib/Support/VirtualFileSystem.cpp')
-rw-r--r-- | llvm/lib/Support/VirtualFileSystem.cpp | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp index de24992..c2ce639 100644 --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -1272,7 +1272,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 @@ -1314,6 +1315,7 @@ class llvm::vfs::RedirectingFileSystemParser { return DE->getLastContent(); } +private: void uniqueOverlayTree(RedirectingFileSystem *FS, RedirectingFileSystem::Entry *SrcE, RedirectingFileSystem::Entry *NewParentE = nullptr) { @@ -1682,6 +1684,61 @@ RedirectingFileSystem::create(std::unique_ptr<MemoryBuffer> Buffer, return FS; } +std::unique_ptr<RedirectingFileSystem> RedirectingFileSystem::create( + ArrayRef<std::pair<std::string, std::string>> RemappedFiles, + bool UseExternalNames, FileSystem &ExternalFS) { + std::unique_ptr<RedirectingFileSystem> FS( + new RedirectingFileSystem(&ExternalFS)); + FS->UseExternalNames = UseExternalNames; + + StringMap<RedirectingFileSystem::Entry *> 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"); + } + + // 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<RedirectingFileSystem::RedirectingFileEntry>( + llvm::sys::path::filename(From), To, + UseExternalNames + ? RedirectingFileSystem::RedirectingFileEntry::NK_External + : RedirectingFileSystem::RedirectingFileEntry::NK_Virtual); + ToEntry = NewFile.get(); + cast<RedirectingFileSystem::RedirectingDirectoryEntry>(Parent)->addContent( + std::move(NewFile)); + } + + return FS; +} + ErrorOr<RedirectingFileSystem::Entry *> RedirectingFileSystem::lookupPath(const Twine &Path_) const { SmallString<256> Path; |