13 #ifndef LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H
14 #define LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H
17 #include "llvm/ADT/IntrusiveRefCntPtr.h"
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/Support/ErrorOr.h"
20 #include "llvm/Support/FileSystem.h"
21 #include "llvm/Support/SourceMgr.h"
22 #include "llvm/Support/raw_ostream.h"
35 llvm::sys::fs::UniqueID UID;
36 llvm::sys::TimeValue MTime;
40 llvm::sys::fs::file_type
Type;
41 llvm::sys::fs::perms Perms;
47 Status() :
Type(llvm::sys::fs::file_type::status_error) {}
49 Status(StringRef Name, llvm::sys::fs::UniqueID UID,
50 llvm::sys::TimeValue MTime, uint32_t User, uint32_t Group,
51 uint64_t Size, llvm::sys::fs::file_type
Type,
52 llvm::sys::fs::perms Perms);
60 StringRef
getName()
const {
return Name; }
93 virtual llvm::ErrorOr<Status>
status() = 0;
95 virtual llvm::ErrorOr<std::string>
getName() {
102 virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
104 bool RequiresNullTerminator =
true,
bool IsVolatile =
false) = 0;
106 virtual std::error_code
close() = 0;
124 std::shared_ptr<detail::DirIterImpl> Impl;
128 : Impl(std::move(I)) {
129 assert(Impl.get() !=
nullptr &&
"requires non-null implementation");
130 if (!Impl->CurrentEntry.isStatusKnown())
139 assert(Impl &&
"attempting to increment past end");
140 EC = Impl->increment();
141 if (EC || !Impl->CurrentEntry.isStatusKnown())
150 if (Impl && RHS.Impl)
151 return Impl->CurrentEntry.equivalent(RHS.Impl->CurrentEntry);
152 return !Impl && !RHS.Impl;
155 return !(*
this == RHS);
164 typedef std::stack<directory_iterator, std::vector<directory_iterator>>
168 std::shared_ptr<IterState> State;
172 std::error_code &EC);
183 return State == Other.State;
186 return !(*
this == RHS);
190 assert(State->size() &&
"Cannot get level without any iteration state");
191 return State->size()-1;
196 class FileSystem :
public llvm::ThreadSafeRefCountedBase<FileSystem> {
201 virtual llvm::ErrorOr<Status>
status(
const Twine &Path) = 0;
203 virtual llvm::ErrorOr<std::unique_ptr<File>>
208 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
210 bool RequiresNullTerminator =
true,
bool IsVolatile =
false);
215 std::error_code &EC) = 0;
224 bool exists(
const Twine &Path);
265 llvm::ErrorOr<Status>
status(
const Twine &Path)
override;
266 llvm::ErrorOr<std::unique_ptr<File>>
283 class InMemoryDirectory;
288 std::unique_ptr<detail::InMemoryDirectory> Root;
289 std::string WorkingDirectory;
290 bool UseNormalizedPaths =
true;
298 bool addFile(
const Twine &Path, time_t ModificationTime,
299 std::unique_ptr<llvm::MemoryBuffer>
Buffer);
303 bool addFileNoOwn(
const Twine &Path, time_t ModificationTime,
304 llvm::MemoryBuffer *Buffer);
309 llvm::ErrorOr<Status>
status(
const Twine &Path)
override;
310 llvm::ErrorOr<std::unique_ptr<File>>
314 return WorkingDirectory;
326 llvm::SourceMgr::DiagHandlerTy DiagHandler,
327 StringRef YAMLFilePath,
328 void *DiagContext =
nullptr,
339 std::vector<YAMLVFSEntry> Mappings;
343 std::string OverlayDir;
349 IsCaseSensitive = CaseSensitive;
352 UseExternalNames = UseExtNames;
355 IsOverlayRelative =
true;
356 OverlayDir.assign(OverlayDirectory.str());
359 void write(llvm::raw_ostream &OS);
const Status * operator->() const
bool addFile(const Twine &Path, time_t ModificationTime, std::unique_ptr< llvm::MemoryBuffer > Buffer)
Add a buffer to the VFS with a path.
const Status * operator->() const
IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
void setOverlayDir(StringRef OverlayDirectory)
virtual llvm::ErrorOr< Status > status()=0
Get the status of the file.
The base class of the type hierarchy.
bool equivalent(const Status &Other) const
std::unique_ptr< llvm::MemoryBuffer > Buffer
bool isStatusKnown() const
llvm::sys::TimeValue getLastModificationTime() const
virtual llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBuffer(const Twine &Name, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false)=0
Get the contents of the file as a MemoryBuffer.
virtual llvm::ErrorOr< std::unique_ptr< File > > openFileForRead(const Twine &Path)=0
Get a File object for the file at Path, if one exists.
virtual directory_iterator dir_begin(const Twine &Dir, std::error_code &EC)=0
Get a directory_iterator for Dir.
bool useNormalizedPaths() const
Return true if this file system normalizes . and .. in paths.
The virtual file system interface.
llvm::ErrorOr< std::string > getCurrentWorkingDirectory() const override
Get the working directory of this file system.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
void write(llvm::raw_ostream &OS)
virtual std::error_code close()=0
Closes the file.
IntrusiveRefCntPtr< FileSystem > getVFSFromYAML(std::unique_ptr< llvm::MemoryBuffer > Buffer, llvm::SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath, void *DiagContext=nullptr, IntrusiveRefCntPtr< FileSystem > ExternalFS=getRealFileSystem())
Gets a FileSystem for a virtual file system described in YAML format.
An input iterator over the recursive contents of a virtual path, similar to llvm::sys::fs::recursive_...
directory_iterator(std::shared_ptr< detail::DirIterImpl > I)
An in-memory file system.
directory_iterator()
Construct an 'end' iterator.
directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override
Get a directory_iterator for Dir.
bool addFileNoOwn(const Twine &Path, time_t ModificationTime, llvm::MemoryBuffer *Buffer)
Add a buffer to the VFS with a path.
directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override
Get a directory_iterator for Dir.
A file system that allows overlaying one AbstractFileSystem on top of another.
virtual llvm::ErrorOr< Status > status(const Twine &Path)=0
Get the status of the entry at Path, if one exists.
directory_iterator & increment(std::error_code &EC)
Equivalent to operator++, with an error code.
llvm::sys::fs::file_type getType() const
void addFileMapping(StringRef VirtualPath, StringRef RealPath)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
bool operator!=(const recursive_directory_iterator &RHS) const
FileSystemList::reverse_iterator iterator
llvm::ErrorOr< std::unique_ptr< File > > openFileForRead(const Twine &Path) override
Get a File object for the file at Path, if one exists.
The result of a status operation.
void pushOverlay(IntrusiveRefCntPtr< FileSystem > FS)
Pushes a file system on top of the stack.
detail::InMemoryDirectory::const_iterator I
recursive_directory_iterator()
Construct an 'end' iterator.
virtual std::error_code setCurrentWorkingDirectory(const Twine &Path)=0
Set the working directory.
llvm::sys::fs::UniqueID getUniqueID() const
virtual llvm::ErrorOr< std::string > getCurrentWorkingDirectory() const =0
Get the working directory of this file system.
static Status copyWithNewName(const Status &In, StringRef NewName)
Get a copy of a Status with a different name.
iterator overlays_end()
Get an iterator pointing one-past the least recently added file system.
void setCaseSensitivity(bool CaseSensitive)
llvm::ErrorOr< std::string > getCurrentWorkingDirectory() const override
Get the working directory of this file system.
virtual llvm::ErrorOr< std::string > getName()
Get the name of the file.
~InMemoryFileSystem() override
InMemoryFileSystem(bool UseNormalizedPaths=true)
recursive_directory_iterator & increment(std::error_code &EC)
Equivalent to operator++, with an error code.
bool operator!=(const directory_iterator &RHS) const
std::string toString() const
llvm::ErrorOr< std::unique_ptr< File > > openFileForRead(const Twine &Path) override
Get a File object for the file at Path, if one exists.
uint32_t getGroup() const
iterator overlays_begin()
Get an iterator pointing to the most recently added file system.
YAMLVFSEntry(T1 &&VPath, T2 &&RPath)
std::error_code setCurrentWorkingDirectory(const Twine &Path) override
Set the working directory.
bool isRegularFile() const
int level() const
Gets the current level. Starting path is at level 0.
bool operator==(const directory_iterator &RHS) const
llvm::sys::fs::perms getPermissions() const
OverlayFileSystem(IntrusiveRefCntPtr< FileSystem > Base)
llvm::sys::fs::UniqueID getNextVirtualUniqueID()
Get a globally unique ID for a virtual file or directory.
const Status & operator*() const
bool exists(const Twine &Path)
Check whether a file exists. Provided for convenience.
const Status & operator*() const
void setUseExternalNames(bool UseExtNames)
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(const Twine &Name, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false)
This is a convenience method that opens a file, gets its content and then closes the file...
StringRef getName() const
Returns the name that should be used for this file or directory.
virtual ~File()
Destroy the file after closing it (if open).
An input iterator over the entries in a virtual path, similar to llvm::sys::fs::directory_iterator.
llvm::ErrorOr< Status > status(const Twine &Path) override
Get the status of the entry at Path, if one exists.
std::error_code setCurrentWorkingDirectory(const Twine &Path) override
Set the working directory.
bool operator==(const recursive_directory_iterator &Other) const
An interface for virtual file systems to provide an iterator over the (non-recursive) contents of a d...
llvm::ErrorOr< Status > status(const Twine &Path) override
Get the status of the entry at Path, if one exists.
virtual std::error_code increment()=0
Sets CurrentEntry to the next entry in the directory on success, or returns a system-defined error_co...
std::error_code makeAbsolute(SmallVectorImpl< char > &Path) const
Make Path an absolute path.