diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2015-10-12 16:16:39 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2015-10-12 16:16:39 +0000 |
commit | 71ce376b2f0100a545d7b7b6e54bef4cb0cd13df (patch) | |
tree | 5c1b9d66a34082b709b55442824b6e82253df1b6 /clang/lib/Basic/VirtualFileSystem.cpp | |
parent | b814ef1ad63e738325c3be9f36c607e1aab6060e (diff) | |
download | llvm-71ce376b2f0100a545d7b7b6e54bef4cb0cd13df.zip llvm-71ce376b2f0100a545d7b7b6e54bef4cb0cd13df.tar.gz llvm-71ce376b2f0100a545d7b7b6e54bef4cb0cd13df.tar.bz2 |
[VFS] Let the user decide if they want path normalization.
This is a more principled version of what I did earlier. Path
normalization is generally a good thing, but may break users in strange
environments, e. g. using lots of symlinks. Let the user choose and
default it to on.
This also changes adding a duplicated file into returning an error if
the file contents are different instead of an assertion failure.
Differential Revision: http://reviews.llvm.org/D13658
llvm-svn: 250060
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; |