1//===- VirtualFileSystem.h - Virtual File System Layer ----------*- C++ -*-===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 10/// Defines the virtual file system interface vfs::FileSystem. 12//===----------------------------------------------------------------------===// 14#ifndef LLVM_SUPPORT_VIRTUALFILESYSTEM_H 15#define LLVM_SUPPORT_VIRTUALFILESYSTEM_H 35#include <system_error> 47/// The result of a \p status operation. 59 /// Whether this entity has an external path different from the virtual path, 60 /// and the external path is exposed by leaking it through the abstraction. 61 /// For example, a RedirectingFileSystem will set this for paths where 62 /// UseExternalName is true. 64 /// FIXME: Currently the external path is exposed by replacing the virtual 65 /// path in this Status object. Instead, we should leave the path in the 66 /// Status intact (matching the requested virtual path) - see 67 /// FileManager::getFileRef for how we plan to fix this. 77 /// Get a copy of a Status with a different size. 79 /// Get a copy of a Status with a different name. 84 /// Returns the name that should be used for this file or directory. 87 /// @name Status interface from llvm::sys::fs 97 /// @name Status queries 98 /// These are static queries in llvm::sys::fs. 110/// Represents an open file. 113 /// Destroy the file after closing it (if open). 114 /// Sub-classes should generally call close() inside their destructors. We 115 /// cannot do that from the base class, since close is virtual. 118 /// Get the status of the file. 121 /// Get the name of the file 129 /// Get the contents of the file as a \p MemoryBuffer. 132bool RequiresNullTerminator =
true,
bool IsVolatile =
false) = 0;
137// Get the same file with a different path. 142// Set the file's underlying path. 146/// A member of a directory, yielded by a directory_iterator. 147/// Only information available on most platforms is included. 163/// An interface for virtual file systems to provide an iterator over the 164/// (non-recursive) contents of a directory. 168 /// Sets \c CurrentEntry to the next entry in the directory on success, 169 /// to directory_entry() at end, or returns a system-defined \c error_code. 177/// An input iterator over the entries in a virtual path, similar to 178/// llvm::sys::fs::directory_iterator. 180 std::shared_ptr<detail::DirIterImpl> Impl;
// Input iterator semantics on copy 185assert(Impl.get() !=
nullptr &&
"requires non-null implementation");
186if (Impl->CurrentEntry.path().empty())
187 Impl.reset();
// Normalize the end iterator to Impl == nullptr. 190 /// Construct an 'end' iterator. 193 /// Equivalent to operator++, with an error code. 195assert(Impl &&
"attempting to increment past end");
196 EC = Impl->increment();
197if (Impl->CurrentEntry.path().empty())
198 Impl.reset();
// Normalize the end iterator to Impl == nullptr. 207return Impl->CurrentEntry.path() ==
RHS.Impl->CurrentEntry.path();
208return !Impl && !
RHS.Impl;
211return !(*
this ==
RHS);
219/// Keeps state for the recursive_directory_iterator. 221 std::vector<directory_iterator>
Stack;
225}
// end namespace detail 227/// An input iterator over the recursive contents of a virtual path, 228/// similar to llvm::sys::fs::recursive_directory_iterator. 231 std::shared_ptr<detail::RecDirIterState>
232 State;
// Input iterator semantics on copy. 236 std::error_code &EC);
238 /// Construct an 'end' iterator. 241 /// Equivalent to operator++, with an error code. 248return State ==
Other.State;
// identity 251return !(*
this ==
RHS);
254 /// Gets the current level. Starting path is at level 0. 256assert(!State->Stack.empty() &&
257"Cannot get level without any iteration state");
258return State->Stack.size() - 1;
261voidno_push() { State->HasNoPushRequest =
true; }
264/// The virtual file system interface. 271 /// Get the status of the entry at \p Path, if one exists. 274 /// Get a \p File object for the text file at \p Path, if one exists. 278 /// Get a \p File object for the binary file at \p Path, if one exists. 279 /// Some non-ascii based file systems perform encoding conversions 280 /// when reading as a text file, and this function should be used if 281 /// a file's bytes should be read as-is. On most filesystems, this 282 /// is the same behaviour as openFileForRead. 288 /// This is a convenience method that opens a file, gets its content and then 290 /// The IsText parameter is used to distinguish whether the file should be 291 /// opened as a binary or text file. 294bool RequiresNullTerminator =
true,
bool IsVolatile =
false,
297 /// Get a directory_iterator for \p Dir. 298 /// \note The 'end' iterator is directory_iterator(). 300 std::error_code &EC) = 0;
302 /// Set the working directory. This will affect all following operations on 303 /// this file system and may propagate down for nested file systems. 306 /// Get the working directory of this file system. 309 /// Gets real path of \p Path e.g. collapse all . and .. patterns, resolve 310 /// symlinks. For real file system, this uses `llvm::sys::fs::real_path`. 311 /// This returns errc::operation_not_permitted if not implemented by subclass. 315 /// Check whether \p Path exists. By default this uses \c status(), but 316 /// filesystems may provide a more efficient implementation if available. 319 /// Is the file mounted on a local filesystem? 320virtual std::error_code
isLocal(
constTwine &Path,
bool &Result);
322 /// Make \a Path an absolute path. 324 /// Makes \a Path absolute using the current directory if it is not already. 325 /// An empty \a Path will result in the current directory. 327 /// /absolute/path => /absolute/path 328 /// relative/../path => <current-directory>/relative/../path 330 /// \param Path A path that is modified to be an absolute path. 331 /// \returns success if \a path has been made absolute, otherwise a 332 /// platform-specific error_code. 335 /// \returns true if \p A and \p B represent the same file, or an error or 336 /// false if they do not. 341unsigned IndentLevel = 0)
const{
352#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 358unsigned IndentLevel)
const{
364for (
unsigned i = 0; i < IndentLevel; ++i)
369/// Gets an \p vfs::FileSystem for the 'real' file system, as seen by 370/// the operating system. 371/// The working directory is linked to the process's working directory. 372/// (This is usually thread-hostile). 375/// Create an \p vfs::FileSystem for the 'real' file system, as seen by 376/// the operating system. 377/// It has its own working directory, independent of (but initially equal to) 378/// that of the process. 381/// A file system that allows overlaying one \p AbstractFileSystem on top 384/// Consists of a stack of >=1 \p FileSystem objects, which are treated as being 385/// one merged file system. When there is a directory that exists in more than 386/// one file system, the \p OverlayFileSystem contains a directory containing 387/// the union of their contents. The attributes (permissions, etc.) of the 388/// top-most (most recently added) directory are used. When there is a file 389/// that exists in more than one file system, the file in the top-most file 390/// system overrides the other(s). 394 /// The stack of file systems, implemented as a list in order of 402 /// Pushes a file system on top of the stack. 412 std::error_code
isLocal(
constTwine &Path,
bool &Result)
override;
423 /// Get an iterator pointing to the most recently added file system. 427 /// Get an iterator pointing one-past the least recently added file system. 431 /// Get an iterator pointing to the least recently added file system. 435 /// Get an iterator pointing one-past the most recently added file system. 444unsigned IndentLevel)
const override;
448/// By default, this delegates all calls to the underlying file system. This 449/// is useful when derived file systems want to override some calls and still 450/// proxy other calls. 458return FS->status(Path);
463return FS->openFileForRead(Path);
466return FS->dir_begin(Dir, EC);
469return FS->getCurrentWorkingDirectory();
472return FS->setCurrentWorkingDirectory(Path);
476return FS->getRealPath(Path, Output);
479return FS->isLocal(Path, Result);
487 FS->visitChildFileSystems(Callback);
494virtualvoid anchor()
override;
499classInMemoryDirectory;
507 std::unique_ptr<llvm::MemoryBuffer>
Buffer;
528explicitoperatorbool()
const{
returnstatic_cast<bool>(
Value); }
529operator std::error_code()
const{
returnValue.getError(); }
536/// An in-memory file system. 538 std::unique_ptr<detail::InMemoryDirectory> Root;
539 std::string WorkingDirectory;
540bool UseNormalizedPaths =
true;
549 /// Create node with \p MakeNode and add it into this filesystem at \p Path. 550bool addFile(
constTwine &Path, time_t ModificationTime,
551 std::unique_ptr<llvm::MemoryBuffer> Buffer,
552 std::optional<uint32_t>
User, std::optional<uint32_t> Group,
553 std::optional<llvm::sys::fs::file_type>
Type,
554 std::optional<llvm::sys::fs::perms> Perms,
MakeNodeFn MakeNode);
556 /// Looks up the in-memory node for the path \p P. 557 /// If \p FollowFinalSymlink is true, the returned node is guaranteed to 558 /// not be a symlink and its path may differ from \p P. 560size_t SymlinkDepth = 0)
const;
568 /// Add a file containing a buffer or a directory to the VFS with a 569 /// path. The VFS owns the buffer. If present, User, Group, Type 570 /// and Perms apply to the newly-created file or directory. 571 /// \return true if the file or directory was successfully added, 572 /// false if the file or directory already exists in the file system with 573 /// different contents. 574bool addFile(
constTwine &Path, time_t ModificationTime,
575 std::unique_ptr<llvm::MemoryBuffer> Buffer,
576 std::optional<uint32_t>
User = std::nullopt,
577 std::optional<uint32_t> Group = std::nullopt,
578 std::optional<llvm::sys::fs::file_type>
Type = std::nullopt,
579 std::optional<llvm::sys::fs::perms> Perms = std::nullopt);
581 /// Add a hard link to a file. 583 /// Here hard links are not intended to be fully equivalent to the classical 584 /// filesystem. Both the hard link and the file share the same buffer and 585 /// status (and thus have the same UniqueID). Because of this there is no way 586 /// to distinguish between the link and the file after the link has been 589 /// The \p Target path must be an existing file or a hardlink. The 590 /// \p NewLink file must not have been added before. The \p Target 591 /// path must not be a directory. The \p NewLink node is added as a hard 592 /// link which points to the resolved file of \p Target node. 593 /// \return true if the above condition is satisfied and hardlink was 594 /// successfully created, false otherwise. 597 /// Arbitrary max depth to search through symlinks. We can get into problems 598 /// if a link links to a link that links back to the link, for example. 601 /// Add a symbolic link. Unlike a HardLink, because \p Target doesn't need 602 /// to refer to a file (or refer to anything, as it happens). Also, an 603 /// in-memory directory for \p Target isn't automatically created. 606 time_t ModificationTime,
607 std::optional<uint32_t>
User = std::nullopt,
608 std::optional<uint32_t> Group = std::nullopt,
609 std::optional<llvm::sys::fs::perms> Perms = std::nullopt);
611 /// Add a buffer to the VFS with a path. The VFS does not own the buffer. 612 /// If present, User, Group, Type and Perms apply to the newly-created file 614 /// \return true if the file or directory was successfully added, 615 /// false if the file or directory already exists in the file system with 616 /// different contents. 619 std::optional<uint32_t>
User = std::nullopt,
620 std::optional<uint32_t> Group = std::nullopt,
621 std::optional<llvm::sys::fs::file_type>
Type = std::nullopt,
622 std::optional<llvm::sys::fs::perms> Perms = std::nullopt);
626 /// Return true if this file system normalizes . and .. in paths. 635return WorkingDirectory;
637 /// Canonicalizes \p Path by combining with the current working 638 /// directory and normalizing the path (e.g. remove dots). If the current 639 /// working directory is not set, this returns errc::operation_not_permitted. 641 /// This doesn't resolve symlinks as they are not supported in in-memory file 645 std::error_code
isLocal(
constTwine &Path,
bool &Result)
override;
650unsigned IndentLevel)
const override;
653/// Get a globally unique ID for a virtual file or directory. 656/// Gets a \p FileSystem for a virtual file system described in YAML 658std::unique_ptr<FileSystem>
661StringRef YAMLFilePath,
void *DiagContext =
nullptr,
665template <
typename T1,
typename T2>
677/// A virtual file system parsed from a YAML file. 679/// Currently, this class allows creating virtual files and directories. Virtual 680/// files map to existing external files in \c ExternalFS, and virtual 681/// directories may either map to existing directories in \c ExternalFS or list 682/// their contents in the form of other virtual directories and/or files. 684/// The basic structure of the parsed file is: 687/// 'version': <version number>, 688/// <optional configuration> 690/// <directory entries> 694/// The roots may be absolute or relative. If relative they will be made 695/// absolute against either current working directory or the directory where 696/// the Overlay YAML file is located, depending on the 'root-relative' 699/// All configuration options are optional. 700/// 'case-sensitive': <boolean, default=(true for Posix, false for Windows)> 701/// 'use-external-names': <boolean, default=true> 702/// 'root-relative': <string, one of 'cwd' or 'overlay-dir', default='cwd'> 703/// 'overlay-relative': <boolean, default=false> 704/// 'fallthrough': <boolean, default=true, deprecated - use 'redirecting-with' 706/// 'redirecting-with': <string, one of 'fallthrough', 'fallback', or 707/// 'redirect-only', default='fallthrough'> 709/// To clarify, 'root-relative' option will prepend the current working 710/// directory, or the overlay directory to the 'roots->name' field only if 711/// 'roots->name' is a relative path. On the other hand, when 'overlay-relative' 712/// is set to 'true', external paths will always be prepended with the overlay 713/// directory, even if external paths are not relative paths. The 714/// 'root-relative' option has no interaction with the 'overlay-relative' 717/// Virtual directories that list their contents are represented as 720/// 'type': 'directory', 722/// 'contents': [ <file or directory entries> ] 725/// The default attributes for such virtual directories are: 727/// MTime = now() when created 731/// UniqueID = unspecified unique value 733/// When a path prefix matches such a directory, the next component in the path 734/// is matched against the entries in the 'contents' array. 736/// Re-mapped directories, on the other hand, are represented as 739/// 'type': 'directory-remap', 741/// 'use-external-name': <boolean>, # Optional 742/// 'external-contents': <path to external directory> 745/// and inherit their attributes from the external directory. When a path 746/// prefix matches such an entry, the unmatched components are appended to the 747/// 'external-contents' path, and the resulting path is looked up in the 748/// external file system instead. 750/// Re-mapped files are represented as 755/// 'use-external-name': <boolean>, # Optional 756/// 'external-contents': <path to external file> 759/// Their attributes and file contents are determined by looking up the file at 760/// their 'external-contents' path in the external file system. 762/// For 'file', 'directory' and 'directory-remap' entries the 'name' field may 763/// contain multiple path components (e.g. /path/to/file). However, any 764/// directory in such a path that contains more than one child must be uniquely 765/// represented by a 'directory' entry. 767/// When the 'use-external-name' field is set, calls to \a vfs::File::status() 768/// give the external (remapped) filesystem name instead of the name the file 769/// was accessed by. This is an intentional leak through the \a 770/// RedirectingFileSystem abstraction layer. It enables clients to discover 771/// (and use) the external file location when communicating with users or tools 772/// that don't use the same VFS overlay. 774/// FIXME: 'use-external-name' causes behaviour that's inconsistent with how 775/// "real" filesystems behave. Maybe there should be a separate channel for 778 :
publicRTTIExtends<RedirectingFileSystem, vfs::FileSystem> {
784 /// The type of redirection to perform. 786 /// Lookup the redirected path first (ie. the one specified in 787 /// 'external-contents') and if that fails "fallthrough" to a lookup of the 788 /// originally provided path. 790 /// Lookup the provided path first and if that fails, "fallback" to a 791 /// lookup of the redirected path. 793 /// Only lookup the redirected path, do not lookup the originally provided 798 /// The type of relative path used by Roots. 800 /// The roots are relative to the current working directory. 802 /// The roots are relative to the directory where the Overlay YAML file 807 /// A single file or directory in the VFS. 820 /// A directory in the vfs with explicitly specified contents. 822 std::vector<std::unique_ptr<Entry>> Contents;
826 /// Constructs a directory entry with explicitly specified contents. 832 /// Constructs an empty directory entry. 839 Contents.push_back(std::move(
Content));
852 /// A file or directory in the vfs that is mapped to a file or directory in 853 /// the external filesystem. 855 std::string ExternalContentsPath;
861 :
Entry(K, Name), ExternalContentsPath(ExternalContentsPath),
867 /// Whether to use the external path as the name for this file or directory. 869return UseName ==
NK_NotSet ? GlobalUseExternalName
876switch (
E->getKind()) {
888 /// A directory in the vfs that maps to a directory in the external file 901 /// A file in the vfs that maps to a file in the external file system. 910 /// Represents the result of a path lookup into the RedirectingFileSystem. 912 /// Chain of parent directory entries for \c E. 915 /// The entry the looked-up path corresponds to. 919 /// When the found Entry is a DirectoryRemapEntry, stores the path in the 920 /// external file system that the looked-up path in the virtual file system 922 std::optional<std::string> ExternalRedirect;
928 /// If the found Entry maps the input path to a path in the external 929 /// file system (i.e. it is a FileEntry or DirectoryRemapEntry), returns 932if (isa<DirectoryRemapEntry>(
E))
934if (
auto *FE = dyn_cast<FileEntry>(
E))
935return FE->getExternalContentsPath();
939 /// Get the (canonical) path of the found entry. This uses the as-written 940 /// path components from the VFS specification. 948 /// Canonicalize path by removing ".", "..", "./", components. This is 949 /// a VFS request, do not bother about symlinks in the path components 950 /// but canonicalize in order to perform the correct entry search. 953 /// Get the File status, or error, from the underlying external file system. 954 /// This returns the status with the originally requested name, while looking 955 /// up the entry using a potentially different path. 957constTwine &OriginalPath)
const;
959 /// Make \a Path an absolute path. 961 /// Makes \a Path absolute using the \a WorkingDir if it is not already. 963 /// /absolute/path => /absolute/path 964 /// relative/../path => <WorkingDir>/relative/../path 966 /// \param WorkingDir A path that will be used as the base Dir if \a Path 967 /// is not already absolute. 968 /// \param Path A path that is modified to be an absolute path. 969 /// \returns success if \a path has been made absolute, otherwise a 970 /// platform-specific error_code. 974// In a RedirectingFileSystem, keys can be specified in Posix or Windows 975// style (or even a mixture of both), so this comparison helper allows 976// slashes (representing a root) to match backslashes (and vice versa). Note 977// that, other than the root, path components should not contain slashes or 982return (lhs ==
"/" && rhs ==
"\\") || (lhs ==
"\\" && rhs ==
"/");
985 /// The root(s) of the virtual file system. 986 std::vector<std::unique_ptr<Entry>> Roots;
988 /// The current working directory of the file system. 989 std::string WorkingDirectory;
991 /// The file system to use for external references. 994 /// This represents the directory path that the YAML file is located. 995 /// This will be prefixed to each 'external-contents' if IsRelativeOverlay 996 /// is set. This will also be prefixed to each 'roots->name' if RootRelative 997 /// is set to RootRelativeKind::OverlayDir and the path is relative. 998 std::string OverlayFileDir;
1000 /// @name Configuration 1003 /// Whether to perform case-sensitive comparisons. 1005 /// Currently, case-insensitive matching only works correctly with ASCII. 1008 /// IsRelativeOverlay marks whether a OverlayFileDir path must 1009 /// be prefixed in every 'external-contents' when reading from YAML files. 1010bool IsRelativeOverlay =
false;
1012 /// Whether to use to use the value of 'external-contents' for the 1013 /// names of files. This global value is overridable on a per-file basis. 1014bool UseExternalNames =
true;
1016 /// True if this FS has redirected a lookup. This does not include 1018mutablebool HasBeenUsed =
false;
1020 /// Used to enable or disable updating `HasBeenUsed`. 1021bool UsageTrackingActive =
false;
1023 /// Determines the lookups to perform, as well as their order. See 1024 /// \c RedirectKind for details. 1027 /// Determine the prefix directory if the roots are relative paths. See 1028 /// \c RootRelativeKind for details. 1034 /// Looks up the path <tt>[Start, End)</tt> in \p From, possibly recursing 1035 /// into the contents of \p From if it is a directory. Returns a LookupResult 1036 /// giving the matched entry and, if that entry is a FileEntry or 1037 /// DirectoryRemapEntry, the path it redirects to in the external file system. 1043 /// Get the status for a path with the provided \c LookupResult. 1045const LookupResult &Result);
1048 /// Looks up \p Path in \c Roots and returns a LookupResult giving the 1049 /// matched entry and, if the entry was a FileEntry or DirectoryRemapEntry, 1050 /// the path it redirects to in the external file system. 1053 /// Parses \p Buffer, which is expected to be in YAML format and 1054 /// returns a virtual file system representing its contents. 1055static std::unique_ptr<RedirectingFileSystem>
1056create(std::unique_ptr<MemoryBuffer> Buffer,
1060 /// Redirect each of the remapped files from first to second. 1061static std::unique_ptr<RedirectingFileSystem>
1062create(
ArrayRef<std::pair<std::string, std::string>> RemappedFiles,
1063bool UseExternalNames,
FileSystem &ExternalFS);
1076 std::error_code
isLocal(
constTwine &Path,
bool &Result)
override;
1086 /// Sets the redirection kind to \c Fallthrough if true or \c RedirectOnly 1087 /// otherwise. Will removed in the future, use \c setRedirection instead. 1092 std::vector<llvm::StringRef>
getRoots()
const;
1103unsigned IndentLevel)
const override;
1107/// Collect all pairs of <virtual path, real path> entries from the 1108/// \p YAMLFilePath. This is used by the module dependency collector to forward 1109/// the entries into the reproducer output VFS YAML file. 1111 std::unique_ptr<llvm::MemoryBuffer> Buffer,
1114void *DiagContext =
nullptr,
1118 std::vector<YAMLVFSEntry> Mappings;
1119 std::optional<bool> IsCaseSensitive;
1120 std::optional<bool> IsOverlayRelative;
1121 std::optional<bool> UseExternalNames;
1122 std::string OverlayDir;
1133 IsCaseSensitive = CaseSensitive;
1139 IsOverlayRelative =
true;
1140 OverlayDir.assign(OverlayDirectory.
str());
1143const std::vector<YAMLVFSEntry> &
getMappings()
const{
return Mappings; }
1148/// File system that tracks the number of calls to the underlying file system. 1149/// This is particularly useful when wrapped around \c RealFileSystem to add 1150/// lightweight tracking of expensive syscalls. 1199unsigned IndentLevel)
const override;
1205#endif// LLVM_SUPPORT_VIRTUALFILESYSTEM_H BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Provides ErrorOr<T> smart pointer.
static void makeAbsolute(SmallVectorImpl< char > &Path)
Make Path absolute.
This file defines the RefCountedBase, ThreadSafeRefCountedBase, and IntrusiveRefCntPtr classes.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static void DiagHandler(const SMDiagnostic &Diag, void *Context)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Represents either an error or a value T.
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
Inheritance utility for extensible RTTI.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reverse_iterator rbegin()
std::reverse_iterator< const_iterator > const_reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
void(*)(const SMDiagnostic &, void *Context) DiagHandlerTy
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
Target - Wrapper for Target specific information.
A thread-safe version of RefCountedBase.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
An efficient, type-erasing, non-owning reference to a callable.
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Represents the result of a call to sys::fs::status().
The virtual file system interface.
llvm::function_ref< void(FileSystem &)> VisitCallbackTy
virtual llvm::ErrorOr< std::string > getCurrentWorkingDirectory() const =0
Get the working directory of this file system.
virtual bool exists(const Twine &Path)
Check whether Path exists.
virtual llvm::ErrorOr< std::unique_ptr< File > > openFileForReadBinary(const Twine &Path)
Get a File object for the binary file at Path, if one exists.
virtual std::error_code setCurrentWorkingDirectory(const Twine &Path)=0
Set the working directory.
virtual void printImpl(raw_ostream &OS, PrintType Type, unsigned IndentLevel) const
virtual std::error_code makeAbsolute(SmallVectorImpl< char > &Path) const
Make Path an absolute path.
virtual llvm::ErrorOr< std::unique_ptr< File > > openFileForRead(const Twine &Path)=0
Get a File object for the text file at Path, if one exists.
virtual std::error_code getRealPath(const Twine &Path, SmallVectorImpl< char > &Output)
Gets real path of Path e.g.
virtual directory_iterator dir_begin(const Twine &Dir, std::error_code &EC)=0
Get a directory_iterator for Dir.
void printIndent(raw_ostream &OS, unsigned IndentLevel) const
LLVM_DUMP_METHOD void dump() const
void print(raw_ostream &OS, PrintType Type=PrintType::Contents, unsigned IndentLevel=0) const
virtual void visitChildFileSystems(VisitCallbackTy Callback)
void visit(VisitCallbackTy Callback)
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(const Twine &Name, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false, bool IsText=true)
This is a convenience method that opens a file, gets its content and then closes the file.
llvm::ErrorOr< bool > equivalent(const Twine &A, const Twine &B)
virtual std::error_code isLocal(const Twine &Path, bool &Result)
Is the file mounted on a local filesystem?
virtual llvm::ErrorOr< Status > status(const Twine &Path)=0
Get the status of the entry at Path, if one exists.
static ErrorOr< std::unique_ptr< File > > getWithPath(ErrorOr< std::unique_ptr< File > > Result, const Twine &P)
virtual llvm::ErrorOr< Status > status()=0
Get the status of the file.
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::string > getName()
Get the name of the file.
virtual void setPath(const Twine &Path)
virtual ~File()
Destroy the file after closing it (if open).
virtual std::error_code close()=0
Closes the file.
Adaptor from InMemoryDir::iterator to directory_iterator.
An in-memory file system.
std::error_code isLocal(const Twine &Path, bool &Result) override
directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override
std::error_code getRealPath(const Twine &Path, SmallVectorImpl< char > &Output) override
Canonicalizes Path by combining with the current working directory and normalizing the path (e....
~InMemoryFileSystem() override
static constexpr size_t MaxSymlinkDepth
Arbitrary max depth to search through symlinks.
bool useNormalizedPaths() const
Return true if this file system normalizes . and .. in paths.
void printImpl(raw_ostream &OS, PrintType Type, unsigned IndentLevel) const override
llvm::ErrorOr< std::string > getCurrentWorkingDirectory() const override
bool addHardLink(const Twine &NewLink, const Twine &Target)
Add a hard link to a file.
std::string toString() const
bool addFileNoOwn(const Twine &Path, time_t ModificationTime, const llvm::MemoryBufferRef &Buffer, std::optional< uint32_t > User=std::nullopt, std::optional< uint32_t > Group=std::nullopt, std::optional< llvm::sys::fs::file_type > Type=std::nullopt, std::optional< llvm::sys::fs::perms > Perms=std::nullopt)
Add a buffer to the VFS with a path.
bool addSymbolicLink(const Twine &NewLink, const Twine &Target, time_t ModificationTime, std::optional< uint32_t > User=std::nullopt, std::optional< uint32_t > Group=std::nullopt, std::optional< llvm::sys::fs::perms > Perms=std::nullopt)
Add a symbolic link.
std::error_code setCurrentWorkingDirectory(const Twine &Path) override
llvm::ErrorOr< Status > status(const Twine &Path) override
llvm::ErrorOr< std::unique_ptr< File > > openFileForRead(const Twine &Path) override
A file system that allows overlaying one AbstractFileSystem on top of another.
const_iterator overlays_end() const
const_iterator overlays_begin() const
directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override
reverse_iterator overlays_rbegin()
Get an iterator pointing to the least recently added file system.
const_range overlays_range() const
void visitChildFileSystems(VisitCallbackTy Callback) override
const_reverse_iterator overlays_rend() const
llvm::ErrorOr< std::unique_ptr< File > > openFileForRead(const Twine &Path) override
reverse_iterator overlays_rend()
Get an iterator pointing one-past the most recently added file system.
std::error_code getRealPath(const Twine &Path, SmallVectorImpl< char > &Output) override
std::error_code setCurrentWorkingDirectory(const Twine &Path) override
void pushOverlay(IntrusiveRefCntPtr< FileSystem > FS)
Pushes a file system on top of the stack.
FileSystemList::const_reverse_iterator const_iterator
llvm::ErrorOr< std::string > getCurrentWorkingDirectory() const override
iterator overlays_end()
Get an iterator pointing one-past the least recently added file system.
std::error_code isLocal(const Twine &Path, bool &Result) override
bool exists(const Twine &Path) override
llvm::ErrorOr< Status > status(const Twine &Path) override
iterator overlays_begin()
Get an iterator pointing to the most recently added file system.
const_reverse_iterator overlays_rbegin() const
FileSystemList::reverse_iterator iterator
void printImpl(raw_ostream &OS, PrintType Type, unsigned IndentLevel) const override
By default, this delegates all calls to the underlying file system.
llvm::ErrorOr< std::unique_ptr< File > > openFileForRead(const Twine &Path) override
void visitChildFileSystems(VisitCallbackTy Callback) override
std::error_code getRealPath(const Twine &Path, SmallVectorImpl< char > &Output) override
directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override
llvm::ErrorOr< Status > status(const Twine &Path) override
bool exists(const Twine &Path) override
std::error_code setCurrentWorkingDirectory(const Twine &Path) override
std::error_code isLocal(const Twine &Path, bool &Result) override
ProxyFileSystem(IntrusiveRefCntPtr< FileSystem > FS)
llvm::ErrorOr< std::string > getCurrentWorkingDirectory() const override
FileSystem & getUnderlyingFS() const
Directory iterator implementation for RedirectingFileSystem's directory entries.
A helper class to hold the common YAML parsing state.
A directory in the vfs with explicitly specified contents.
iterator contents_begin()
static bool classof(const Entry *E)
DirectoryEntry(StringRef Name, Status S)
Constructs an empty directory entry.
DirectoryEntry(StringRef Name, std::vector< std::unique_ptr< Entry > > Contents, Status S)
Constructs a directory entry with explicitly specified contents.
decltype(Contents)::iterator iterator
void addContent(std::unique_ptr< Entry > Content)
Entry * getLastContent() const
A directory in the vfs that maps to a directory in the external file system.
DirectoryRemapEntry(StringRef Name, StringRef ExternalContentsPath, NameKind UseName)
static bool classof(const Entry *E)
A single file or directory in the VFS.
StringRef getName() const
EntryKind getKind() const
Entry(EntryKind K, StringRef Name)
A file in the vfs that maps to a file in the external file system.
static bool classof(const Entry *E)
FileEntry(StringRef Name, StringRef ExternalContentsPath, NameKind UseName)
A file or directory in the vfs that is mapped to a file or directory in the external filesystem.
StringRef getExternalContentsPath() const
NameKind getUseName() const
RemapEntry(EntryKind K, StringRef Name, StringRef ExternalContentsPath, NameKind UseName)
bool useExternalName(bool GlobalUseExternalName) const
Whether to use the external path as the name for this file or directory.
static bool classof(const Entry *E)
A virtual file system parsed from a YAML file.
void setUsageTrackingActive(bool Active)
RootRelativeKind
The type of relative path used by Roots.
@ OverlayDir
The roots are relative to the directory where the Overlay YAML file.
@ CWD
The roots are relative to the current working directory.
bool exists(const Twine &Path) override
Check whether Path exists.
void printImpl(raw_ostream &OS, PrintType Type, unsigned IndentLevel) const override
std::vector< llvm::StringRef > getRoots() const
directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override
Get a directory_iterator for Dir.
ErrorOr< LookupResult > lookupPath(StringRef Path) const
Looks up Path in Roots and returns a LookupResult giving the matched entry and, if the entry was a Fi...
RedirectKind
The type of redirection to perform.
@ Fallthrough
Lookup the redirected path first (ie.
@ Fallback
Lookup the provided path first and if that fails, "fallback" to a lookup of the redirected path.
@ RedirectOnly
Only lookup the redirected path, do not lookup the originally provided path.
void setFallthrough(bool Fallthrough)
Sets the redirection kind to Fallthrough if true or RedirectOnly otherwise.
void visitChildFileSystems(VisitCallbackTy Callback) override
std::error_code getRealPath(const Twine &Path, SmallVectorImpl< char > &Output) override
Gets real path of Path e.g.
ErrorOr< std::unique_ptr< File > > openFileForRead(const Twine &Path) override
Get a File object for the text file at Path, if one exists.
void setOverlayFileDir(StringRef PrefixDir)
llvm::ErrorOr< std::string > getCurrentWorkingDirectory() const override
Get the working directory of this file system.
void setRedirection(RedirectingFileSystem::RedirectKind Kind)
std::error_code isLocal(const Twine &Path, bool &Result) override
Is the file mounted on a local filesystem?
static std::unique_ptr< RedirectingFileSystem > create(std::unique_ptr< MemoryBuffer > Buffer, SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath, void *DiagContext, IntrusiveRefCntPtr< FileSystem > ExternalFS)
Parses Buffer, which is expected to be in YAML format and returns a virtual file system representing ...
std::error_code setCurrentWorkingDirectory(const Twine &Path) override
Set the working directory.
StringRef getOverlayFileDir() const
void printEntry(raw_ostream &OS, Entry *E, unsigned IndentLevel=0) const
The result of a status operation.
llvm::sys::fs::perms getPermissions() const
llvm::sys::fs::UniqueID getUniqueID() const
bool equivalent(const Status &Other) const
static Status copyWithNewName(const Status &In, const Twine &NewName)
Get a copy of a Status with a different name.
bool isStatusKnown() const
bool ExposesExternalVFSPath
Whether this entity has an external path different from the virtual path, and the external path is ex...
uint32_t getGroup() const
static Status copyWithNewSize(const Status &In, uint64_t NewSize)
Get a copy of a Status with a different size.
llvm::sys::TimePoint getLastModificationTime() const
llvm::sys::fs::file_type getType() const
bool isRegularFile() const
StringRef getName() const
Returns the name that should be used for this file or directory.
Status(const Twine &Name, llvm::sys::fs::UniqueID UID, llvm::sys::TimePoint<> MTime, uint32_t User, uint32_t Group, uint64_t Size, llvm::sys::fs::file_type Type, llvm::sys::fs::perms Perms)
File system that tracks the number of calls to the underlying file system.
bool exists(const Twine &Path) override
TracingFileSystem(llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS)
ErrorOr< std::unique_ptr< File > > openFileForRead(const Twine &Path) override
std::size_t NumOpenFileForReadCalls
std::size_t NumIsLocalCalls
directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override
std::size_t NumExistsCalls
ErrorOr< Status > status(const Twine &Path) override
void printImpl(raw_ostream &OS, PrintType Type, unsigned IndentLevel) const override
std::error_code isLocal(const Twine &Path, bool &Result) override
std::size_t NumDirBeginCalls
std::size_t NumGetRealPathCalls
std::size_t NumStatusCalls
std::error_code getRealPath(const Twine &Path, SmallVectorImpl< char > &Output) override
void addFileMapping(StringRef VirtualPath, StringRef RealPath)
void setCaseSensitivity(bool CaseSensitive)
void setOverlayDir(StringRef OverlayDirectory)
const std::vector< YAMLVFSEntry > & getMappings() const
void write(llvm::raw_ostream &OS)
void addDirectoryMapping(StringRef VirtualPath, StringRef RealPath)
void setUseExternalNames(bool UseExtNames)
The in memory file system is a tree of Nodes.
std::error_code getError() const
NamedNodeOrError(std::error_code EC)
const detail::InMemoryNode * operator*() const
StringRef getName() const
NamedNodeOrError(llvm::errc EC)
NamedNodeOrError(llvm::SmallString< 128 > Name, const detail::InMemoryNode *Node)
A member of a directory, yielded by a directory_iterator.
directory_entry()=default
directory_entry(std::string Path, llvm::sys::fs::file_type Type)
llvm::StringRef path() const
llvm::sys::fs::file_type type() const
An input iterator over the entries in a virtual path, similar to llvm::sys::fs::directory_iterator.
directory_iterator(std::shared_ptr< detail::DirIterImpl > I)
bool operator==(const directory_iterator &RHS) const
const directory_entry * operator->() const
const directory_entry & operator*() const
directory_iterator & increment(std::error_code &EC)
Equivalent to operator++, with an error code.
bool operator!=(const directory_iterator &RHS) const
directory_iterator()=default
Construct an 'end' iterator.
An input iterator over the recursive contents of a virtual path, similar to llvm::sys::fs::recursive_...
const directory_entry & operator*() const
recursive_directory_iterator()=default
Construct an 'end' iterator.
bool operator!=(const recursive_directory_iterator &RHS) const
bool operator==(const recursive_directory_iterator &Other) const
int level() const
Gets the current level. Starting path is at level 0.
recursive_directory_iterator & increment(std::error_code &EC)
Equivalent to operator++, with an error code.
const directory_entry * operator->() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
file_type
An enumeration for the file system's view of the type.
std::chrono::time_point< std::chrono::system_clock, D > TimePoint
A time point on the system clock.
void collectVFSFromYAML(std::unique_ptr< llvm::MemoryBuffer > Buffer, llvm::SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath, SmallVectorImpl< YAMLVFSEntry > &CollectedEntries, void *DiagContext=nullptr, IntrusiveRefCntPtr< FileSystem > ExternalFS=getRealFileSystem())
Collect all pairs of <virtual path, real path> entries from the YAMLFilePath.
std::unique_ptr< 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.
std::unique_ptr< FileSystem > createPhysicalFileSystem()
Create an vfs::FileSystem for the 'real' file system, as seen by the operating system.
llvm::sys::fs::UniqueID getNextVirtualUniqueID()
Get a globally unique ID for a virtual file or directory.
IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
This is an optimization pass for GlobalISel generic memory operations.
auto reverse(ContainerTy &&C)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
Represents the result of a path lookup into the RedirectingFileSystem.
std::optional< StringRef > getExternalRedirect() const
If the found Entry maps the input path to a path in the external file system (i.e.
Entry * E
The entry the looked-up path corresponds to.
void getPath(llvm::SmallVectorImpl< char > &Path) const
Get the (canonical) path of the found entry.
llvm::SmallVector< Entry *, 32 > Parents
Chain of parent directory entries for E.
YAMLVFSEntry(T1 &&VPath, T2 &&RPath, bool IsDirectory=false)
An interface for virtual file systems to provide an iterator over the (non-recursive) contents of a d...
virtual std::error_code increment()=0
Sets CurrentEntry to the next entry in the directory on success, to directory_entry() at end,...
directory_entry CurrentEntry
Status makeStatus() const
llvm::sys::fs::file_type Type
std::unique_ptr< llvm::MemoryBuffer > Buffer
llvm::sys::fs::perms Perms
llvm::sys::fs::UniqueID DirUID
Keeps state for the recursive_directory_iterator.
std::vector< directory_iterator > Stack