summaryrefslogtreecommitdiff
path: root/include/clang/Basic/VirtualFileSystem.h
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2014-02-20 21:59:23 +0000
committerBen Langmuir <blangmuir@apple.com>2014-02-20 21:59:23 +0000
commitd7596d64125a962565452d5f7f6bac545ec5a082 (patch)
tree48db574f2bb6fed3725cc4148a57f4be48ce9c8c /include/clang/Basic/VirtualFileSystem.h
parent9bce94e59ca9b2afb119f11833227ca6a4eda0ef (diff)
downloadclang-d7596d64125a962565452d5f7f6bac545ec5a082.tar.gz
clang-d7596d64125a962565452d5f7f6bac545ec5a082.tar.bz2
clang-d7596d64125a962565452d5f7f6bac545ec5a082.tar.xz
Recommit virtual file system
Previously reverted in r201755 due to causing an assertion failure. I've removed the offending assertion, and taught the CompilerInstance to create a default virtual file system inside createFileManager. In the future, we should be able to reach into the CompilerInvocation to customize this behaviour without breaking clients that don't care. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@201818 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Basic/VirtualFileSystem.h')
-rw-r--r--include/clang/Basic/VirtualFileSystem.h162
1 files changed, 162 insertions, 0 deletions
diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h
new file mode 100644
index 0000000000..694c6ddec8
--- /dev/null
+++ b/include/clang/Basic/VirtualFileSystem.h
@@ -0,0 +1,162 @@
+//===- VirtualFileSystem.h - Virtual File System Layer ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief Defines the virtual file system interface vfs::FileSystem.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
+#define LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/ErrorOr.h"
+
+namespace llvm {
+class MemoryBuffer;
+}
+
+namespace clang {
+namespace vfs {
+
+/// \brief The result of a \p status operation.
+class Status {
+ std::string Name;
+ std::string ExternalName;
+ llvm::sys::fs::UniqueID UID;
+ llvm::sys::TimeValue MTime;
+ uint32_t User;
+ uint32_t Group;
+ uint64_t Size;
+ llvm::sys::fs::file_type Type;
+ llvm::sys::fs::perms Perms;
+
+public:
+ Status() : Type(llvm::sys::fs::file_type::status_error) {}
+ Status(const llvm::sys::fs::file_status &Status);
+ Status(StringRef Name, StringRef RealName, llvm::sys::fs::UniqueID UID,
+ llvm::sys::TimeValue MTime, uint32_t User, uint32_t Group,
+ uint64_t Size, llvm::sys::fs::file_type Type,
+ llvm::sys::fs::perms Perms);
+
+ /// \brief Returns the name this status was looked up by.
+ StringRef getName() const { return Name; }
+
+ /// \brief Returns the name to use outside the compiler.
+ ///
+ /// For example, in diagnostics or debug info we should use this name.
+ StringRef getExternalName() const { return ExternalName; }
+
+ void setName(StringRef N) { Name = N; }
+ void setExternalName(StringRef N) { ExternalName = N; }
+
+ /// @name Status interface from llvm::sys::fs
+ /// @{
+ llvm::sys::fs::file_type getType() const { return Type; }
+ llvm::sys::fs::perms getPermissions() const { return Perms; }
+ llvm::sys::TimeValue getLastModificationTime() const { return MTime; }
+ llvm::sys::fs::UniqueID getUniqueID() const { return UID; }
+ uint32_t getUser() const { return User; }
+ uint32_t getGroup() const { return Group; }
+ uint64_t getSize() const { return Size; }
+ void setType(llvm::sys::fs::file_type v) { Type = v; }
+ void setPermissions(llvm::sys::fs::perms p) { Perms = p; }
+ /// @}
+ /// @name Status queries
+ /// These are static queries in llvm::sys::fs.
+ /// @{
+ bool equivalent(const Status &Other) const;
+ bool isDirectory() const;
+ bool isRegularFile() const;
+ bool isOther() const;
+ bool isSymlink() const;
+ bool isStatusKnown() const;
+ bool exists() const;
+ /// @}
+};
+
+/// \brief Represents an open file.
+class File {
+public:
+ /// \brief Destroy the file after closing it (if open).
+ /// Sub-classes should generally call close() inside their destructors. We
+ /// cannot do that from the base class, since close is virtual.
+ virtual ~File();
+ /// \brief Get the status of the file.
+ virtual llvm::ErrorOr<Status> status() = 0;
+ /// \brief Get the contents of the file as a \p MemoryBuffer.
+ virtual llvm::error_code getBuffer(const Twine &Name,
+ OwningPtr<llvm::MemoryBuffer> &Result,
+ int64_t FileSize = -1,
+ bool RequiresNullTerminator = true) = 0;
+ /// \brief Closes the file.
+ virtual llvm::error_code close() = 0;
+};
+
+/// \brief The virtual file system interface.
+class FileSystem : public RefCountedBase<FileSystem> {
+public:
+ virtual ~FileSystem();
+
+ /// \brief Get the status of the entry at \p Path, if one exists.
+ virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0;
+ /// \brief Get a \p File object for the file at \p Path, if one exists.
+ virtual llvm::error_code openFileForRead(const Twine &Path,
+ OwningPtr<File> &Result) = 0;
+
+ /// This is a convenience method that opens a file, gets its content and then
+ /// closes the file.
+ llvm::error_code getBufferForFile(const Twine &Name,
+ OwningPtr<llvm::MemoryBuffer> &Result,
+ int64_t FileSize = -1,
+ bool RequiresNullTerminator = true);
+};
+
+/// \brief Gets an \p vfs::FileSystem for the 'real' file system, as seen by
+/// the operating system.
+IntrusiveRefCntPtr<FileSystem> getRealFileSystem();
+
+/// \brief A file system that allows overlaying one \p AbstractFileSystem on top
+/// of another.
+///
+/// Consists of a stack of >=1 \p FileSytem objects, which are treated as being
+/// one merged file system. When there is a directory that exists in more than
+/// one file system, the \p OverlayFileSystem contains a directory containing
+/// the union of their contents. The attributes (permissions, etc.) of the
+/// top-most (most recently added) directory are used. When there is a file
+/// that exists in more than one file system, the file in the top-most file
+/// system overrides the other(s).
+class OverlayFileSystem : public FileSystem {
+ typedef SmallVector<IntrusiveRefCntPtr<FileSystem>, 1> FileSystemList;
+ typedef FileSystemList::reverse_iterator iterator;
+
+ /// \brief The stack of file systems, implemented as a list in order of
+ /// their addition.
+ FileSystemList FSList;
+
+ /// \brief Get an iterator pointing to the most recently added file system.
+ iterator overlays_begin() { return FSList.rbegin(); }
+
+ /// \brief Get an iterator pointing one-past the least recently added file
+ /// system.
+ iterator overlays_end() { return FSList.rend(); }
+
+public:
+ OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> Base);
+ /// \brief Pushes a file system on top of the stack.
+ void pushOverlay(IntrusiveRefCntPtr<FileSystem> FS);
+
+ llvm::ErrorOr<Status> status(const Twine &Path) LLVM_OVERRIDE;
+ llvm::error_code openFileForRead(const Twine &Path,
+ OwningPtr<File> &Result) LLVM_OVERRIDE;
+};
+
+} // end namespace vfs
+} // end namespace clang
+#endif // LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H