aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/VirtualFileSystem.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2020-11-11 23:03:38 -0500
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2020-12-08 17:53:30 -0800
commit75cd8d756d6e88b075fae8fe631fdbb17802bdb8 (patch)
treedf4bde4ec81beb710efb58420cc24f4111f649b7 /llvm/lib/Support/VirtualFileSystem.cpp
parenta22eda548b8e1f9362018dec194af0ca91b35da0 (diff)
downloadllvm-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.cpp59
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;