summaryrefslogtreecommitdiffstats
path: root/clang/lib/Basic
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2015-10-12 16:16:39 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2015-10-12 16:16:39 +0000
commit71ce376b2f0100a545d7b7b6e54bef4cb0cd13df (patch)
tree5c1b9d66a34082b709b55442824b6e82253df1b6 /clang/lib/Basic
parentb814ef1ad63e738325c3be9f36c607e1aab6060e (diff)
downloadbcm5719-llvm-71ce376b2f0100a545d7b7b6e54bef4cb0cd13df.tar.gz
bcm5719-llvm-71ce376b2f0100a545d7b7b6e54bef4cb0cd13df.zip
[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')
-rw-r--r--clang/lib/Basic/VirtualFileSystem.cpp46
1 files changed, 30 insertions, 16 deletions
diff --git a/clang/lib/Basic/VirtualFileSystem.cpp b/clang/lib/Basic/VirtualFileSystem.cpp
index 1b75fbefd2a..a20132b3de8 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;
OpenPOWER on IntegriCloud