diff options
Diffstat (limited to 'clang/lib/Basic/VirtualFileSystem.cpp')
-rw-r--r-- | clang/lib/Basic/VirtualFileSystem.cpp | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/clang/lib/Basic/VirtualFileSystem.cpp b/clang/lib/Basic/VirtualFileSystem.cpp index 1b75fbe..a20132b 100644 --- a/clang/lib/Basic/VirtualFileSystem.cpp +++ b/clang/lib/Basic/VirtualFileSystem.cpp @@ -10,6 +10,7 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/VirtualFileSystem.h" +#include "clang/Basic/FileManager.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" @@ -474,11 +475,12 @@ public: }; } -InMemoryFileSystem::InMemoryFileSystem() +InMemoryFileSystem::InMemoryFileSystem(bool UseNormalizedPaths) : Root(new detail::InMemoryDirectory( Status("", getNextVirtualUniqueID(), llvm::sys::TimeValue::MinTime(), 0, 0, 0, llvm::sys::fs::file_type::directory_file, - llvm::sys::fs::perms::all_all))) {} + llvm::sys::fs::perms::all_all))), + UseNormalizedPaths(UseNormalizedPaths) {} InMemoryFileSystem::~InMemoryFileSystem() {} @@ -486,7 +488,7 @@ std::string InMemoryFileSystem::toString() const { return Root->toString(/*Indent=*/0); } -void InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, +bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, std::unique_ptr<llvm::MemoryBuffer> Buffer) { SmallString<128> Path; P.toVector(Path); @@ -496,14 +498,14 @@ void InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, assert(!EC); (void)EC; - detail::InMemoryDirectory *Dir = Root.get(); - auto I = llvm::sys::path::begin(Path), E = llvm::sys::path::end(Path); - if (*I == ".") - ++I; + if (useNormalizedPaths()) + FileManager::removeDotPaths(Path, /*RemoveDotDot=*/true); - if (I == E) - return; + if (Path.empty()) + return false; + detail::InMemoryDirectory *Dir = Root.get(); + auto I = llvm::sys::path::begin(Path), E = llvm::sys::path::end(Path); while (true) { StringRef Name = *I; detail::InMemoryNode *Node = Dir->getChild(Name); @@ -519,7 +521,7 @@ void InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, llvm::sys::fs::all_all); Dir->addChild(Name, llvm::make_unique<detail::InMemoryFile>( std::move(Stat), std::move(Buffer))); - return; + return true; } // Create a new directory. Use the path up to here. @@ -534,12 +536,24 @@ void InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, continue; } - if (auto *NewDir = dyn_cast<detail::InMemoryDirectory>(Node)) + if (auto *NewDir = dyn_cast<detail::InMemoryDirectory>(Node)) { Dir = NewDir; + } else { + assert(isa<detail::InMemoryFile>(Node) && + "Must be either file or directory!"); + + // Trying to insert a directory in place of a file. + if (I != E) + return false; + + // Return false only if the new file is different from the existing one. + return cast<detail::InMemoryFile>(Node)->getBuffer()->getBuffer() == + Buffer->getBuffer(); + } } } -void InMemoryFileSystem::addFileNoOwn(const Twine &P, time_t ModificationTime, +bool InMemoryFileSystem::addFileNoOwn(const Twine &P, time_t ModificationTime, llvm::MemoryBuffer *Buffer) { return addFile(P, ModificationTime, llvm::MemoryBuffer::getMemBuffer( @@ -557,13 +571,13 @@ lookupInMemoryNode(const InMemoryFileSystem &FS, detail::InMemoryDirectory *Dir, assert(!EC); (void)EC; - auto I = llvm::sys::path::begin(Path), E = llvm::sys::path::end(Path); - if (*I == ".") - ++I; + if (FS.useNormalizedPaths()) + FileManager::removeDotPaths(Path, /*RemoveDotDot=*/true); - if (I == E) + if (Path.empty()) return Dir; + auto I = llvm::sys::path::begin(Path), E = llvm::sys::path::end(Path); while (true) { detail::InMemoryNode *Node = Dir->getChild(*I); ++I; |