summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/VirtualFileSystem.h4
-rw-r--r--clang/lib/Basic/VirtualFileSystem.cpp16
-rw-r--r--clang/lib/Format/Format.cpp15
-rw-r--r--clang/tools/clang-format/ClangFormat.cpp24
-rw-r--r--clang/unittests/Basic/VirtualFileSystemTest.cpp12
5 files changed, 54 insertions, 17 deletions
diff --git a/clang/include/clang/Basic/VirtualFileSystem.h b/clang/include/clang/Basic/VirtualFileSystem.h
index 52bcce2cd1e..36a14b794ce 100644
--- a/clang/include/clang/Basic/VirtualFileSystem.h
+++ b/clang/include/clang/Basic/VirtualFileSystem.h
@@ -274,8 +274,12 @@ class InMemoryFileSystem : public FileSystem {
public:
InMemoryFileSystem();
~InMemoryFileSystem() override;
+ /// Add a buffer to the VFS with a path. The VFS owns the buffer.
void addFile(const Twine &Path, time_t ModificationTime,
std::unique_ptr<llvm::MemoryBuffer> Buffer);
+ /// Add a buffer to the VFS with a path. The VFS does not own the buffer.
+ void addFileNoOwn(const Twine &Path, time_t ModificationTime,
+ llvm::MemoryBuffer *Buffer);
StringRef toString() const;
llvm::ErrorOr<Status> status(const Twine &Path) override;
diff --git a/clang/lib/Basic/VirtualFileSystem.cpp b/clang/lib/Basic/VirtualFileSystem.cpp
index 3864b19767f..5486331d4af 100644
--- a/clang/lib/Basic/VirtualFileSystem.cpp
+++ b/clang/lib/Basic/VirtualFileSystem.cpp
@@ -528,6 +528,13 @@ void InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime,
}
}
+void InMemoryFileSystem::addFileNoOwn(const Twine &P, time_t ModificationTime,
+ llvm::MemoryBuffer *Buffer) {
+ return addFile(P, ModificationTime,
+ llvm::MemoryBuffer::getMemBuffer(
+ Buffer->getBuffer(), Buffer->getBufferIdentifier()));
+}
+
static ErrorOr<detail::InMemoryNode *>
lookupInMemoryNode(const InMemoryFileSystem &FS, detail::InMemoryDirectory *Dir,
const Twine &P) {
@@ -541,6 +548,15 @@ lookupInMemoryNode(const InMemoryFileSystem &FS, detail::InMemoryDirectory *Dir,
auto I = llvm::sys::path::begin(Path), E = llvm::sys::path::end(Path);
while (true) {
+ // Skip over ".".
+ // FIXME: Also handle "..".
+ if (*I == ".") {
+ ++I;
+ if (I == E)
+ return Dir;
+ continue;
+ }
+
detail::InMemoryNode *Node = Dir->getChild(*I);
++I;
if (!Node)
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index fffd80cb682..62f94b8f99f 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1792,18 +1792,17 @@ tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
if (Style.DisableFormat)
return tooling::Replacements();
- FileManager Files((FileSystemOptions()));
+ IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
+ new vfs::InMemoryFileSystem);
+ FileManager Files(FileSystemOptions(), InMemoryFileSystem);
DiagnosticsEngine Diagnostics(
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
new DiagnosticOptions);
SourceManager SourceMgr(Diagnostics, Files);
- std::unique_ptr<llvm::MemoryBuffer> Buf =
- llvm::MemoryBuffer::getMemBuffer(Code, FileName);
- const clang::FileEntry *Entry =
- Files.getVirtualFile(FileName, Buf->getBufferSize(), 0);
- SourceMgr.overrideFileContents(Entry, std::move(Buf));
- FileID ID =
- SourceMgr.createFileID(Entry, SourceLocation(), clang::SrcMgr::C_User);
+ InMemoryFileSystem->addFile(FileName, 0,
+ llvm::MemoryBuffer::getMemBuffer(Code, FileName));
+ FileID ID = SourceMgr.createFileID(Files.getFile(FileName), SourceLocation(),
+ clang::SrcMgr::C_User);
SourceLocation StartOfFile = SourceMgr.getLocForStartOfFile(ID);
std::vector<CharSourceRange> CharRanges;
for (const tooling::Range &Range : Ranges) {
diff --git a/clang/tools/clang-format/ClangFormat.cpp b/clang/tools/clang-format/ClangFormat.cpp
index 8917818a0a8..95b53524ff8 100644
--- a/clang/tools/clang-format/ClangFormat.cpp
+++ b/clang/tools/clang-format/ClangFormat.cpp
@@ -109,11 +109,11 @@ namespace clang {
namespace format {
static FileID createInMemoryFile(StringRef FileName, MemoryBuffer *Source,
- SourceManager &Sources, FileManager &Files) {
- const FileEntry *Entry = Files.getVirtualFile(FileName,
- Source->getBufferSize(), 0);
- Sources.overrideFileContents(Entry, Source, true);
- return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
+ SourceManager &Sources, FileManager &Files,
+ vfs::InMemoryFileSystem *MemFS) {
+ MemFS->addFileNoOwn(FileName, 0, Source);
+ return Sources.createFileID(Files.getFile(FileName), SourceLocation(),
+ SrcMgr::C_User);
}
// Parses <start line>:<end line> input to a pair of line numbers.
@@ -127,12 +127,15 @@ static bool parseLineRange(StringRef Input, unsigned &FromLine,
static bool fillRanges(MemoryBuffer *Code,
std::vector<tooling::Range> &Ranges) {
- FileManager Files((FileSystemOptions()));
+ IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
+ new vfs::InMemoryFileSystem);
+ FileManager Files(FileSystemOptions(), InMemoryFileSystem);
DiagnosticsEngine Diagnostics(
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
new DiagnosticOptions);
SourceManager Sources(Diagnostics, Files);
- FileID ID = createInMemoryFile("<irrelevant>", Code, Sources, Files);
+ FileID ID = createInMemoryFile("<irrelevant>", Code, Sources, Files,
+ InMemoryFileSystem.get());
if (!LineRanges.empty()) {
if (!Offsets.empty() || !Lengths.empty()) {
llvm::errs() << "error: cannot use -lines with -offset/-length\n";
@@ -269,12 +272,15 @@ static bool format(StringRef FileName) {
outputReplacementsXML(Replaces);
llvm::outs() << "</replacements>\n";
} else {
- FileManager Files((FileSystemOptions()));
+ IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
+ new vfs::InMemoryFileSystem);
+ FileManager Files(FileSystemOptions(), InMemoryFileSystem);
DiagnosticsEngine Diagnostics(
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
new DiagnosticOptions);
SourceManager Sources(Diagnostics, Files);
- FileID ID = createInMemoryFile(AssumedFileName, Code.get(), Sources, Files);
+ FileID ID = createInMemoryFile(AssumedFileName, Code.get(), Sources, Files,
+ InMemoryFileSystem.get());
Rewriter Rewrite(Sources, LangOptions());
tooling::applyAllReplacements(Replaces, Rewrite);
if (Inplace) {
diff --git a/clang/unittests/Basic/VirtualFileSystemTest.cpp b/clang/unittests/Basic/VirtualFileSystemTest.cpp
index 4d4522a85b4..ccfac28dc7b 100644
--- a/clang/unittests/Basic/VirtualFileSystemTest.cpp
+++ b/clang/unittests/Basic/VirtualFileSystemTest.cpp
@@ -548,17 +548,29 @@ TEST_F(InMemoryFileSystemTest, OverlayFile) {
FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
auto Stat = FS.status("/");
ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
+ Stat = FS.status("/.");
+ ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
Stat = FS.status("/a");
ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
ASSERT_EQ("/a", Stat->getName());
}
+TEST_F(InMemoryFileSystemTest, OverlayFileNoOwn) {
+ auto Buf = MemoryBuffer::getMemBuffer("a");
+ FS.addFileNoOwn("/a", 0, Buf.get());
+ auto Stat = FS.status("/a");
+ ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+ ASSERT_EQ("/a", Stat->getName());
+}
+
TEST_F(InMemoryFileSystemTest, OpenFileForRead) {
FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
auto File = FS.openFileForRead("/a");
ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
File = FS.openFileForRead("/a"); // Open again.
ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
+ File = FS.openFileForRead("/././a"); // Open again.
+ ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
File = FS.openFileForRead("/");
ASSERT_EQ(File.getError(), errc::invalid_argument) << FS.toString();
File = FS.openFileForRead("/b");
OpenPOWER on IntegriCloud