LLVM  9.0.0svn
VirtualFileSystem.h
Go to the documentation of this file.
1 //===- VirtualFileSystem.h - Virtual File System Layer ----------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// Defines the virtual file system interface vfs::FileSystem.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_SUPPORT_VIRTUALFILESYSTEM_H
15 #define LLVM_SUPPORT_VIRTUALFILESYSTEM_H
16 
18 #include "llvm/ADT/None.h"
19 #include "llvm/ADT/Optional.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/Support/Chrono.h"
24 #include "llvm/Support/ErrorOr.h"
26 #include "llvm/Support/Path.h"
27 #include "llvm/Support/SourceMgr.h"
28 #include <cassert>
29 #include <cstdint>
30 #include <ctime>
31 #include <memory>
32 #include <stack>
33 #include <string>
34 #include <system_error>
35 #include <utility>
36 #include <vector>
37 
38 namespace llvm {
39 
40 class MemoryBuffer;
41 
42 namespace vfs {
43 
44 /// The result of a \p status operation.
45 class Status {
46  std::string Name;
49  uint32_t User;
50  uint32_t Group;
51  uint64_t Size;
54 
55 public:
56  // FIXME: remove when files support multiple names
57  bool IsVFSMapped = false;
58 
59  Status() = default;
62  llvm::sys::TimePoint<> MTime, uint32_t User, uint32_t Group,
63  uint64_t Size, llvm::sys::fs::file_type Type,
64  llvm::sys::fs::perms Perms);
65 
66  /// Get a copy of a Status with a different name.
67  static Status copyWithNewName(const Status &In, StringRef NewName);
69  StringRef NewName);
70 
71  /// Returns the name that should be used for this file or directory.
72  StringRef getName() const { return Name; }
73 
74  /// @name Status interface from llvm::sys::fs
75  /// @{
76  llvm::sys::fs::file_type getType() const { return Type; }
77  llvm::sys::fs::perms getPermissions() const { return Perms; }
79  llvm::sys::fs::UniqueID getUniqueID() const { return UID; }
80  uint32_t getUser() const { return User; }
81  uint32_t getGroup() const { return Group; }
82  uint64_t getSize() const { return Size; }
83  /// @}
84  /// @name Status queries
85  /// These are static queries in llvm::sys::fs.
86  /// @{
87  bool equivalent(const Status &Other) const;
88  bool isDirectory() const;
89  bool isRegularFile() const;
90  bool isOther() const;
91  bool isSymlink() const;
92  bool isStatusKnown() const;
93  bool exists() const;
94  /// @}
95 };
96 
97 /// Represents an open file.
98 class File {
99 public:
100  /// Destroy the file after closing it (if open).
101  /// Sub-classes should generally call close() inside their destructors. We
102  /// cannot do that from the base class, since close is virtual.
103  virtual ~File();
104 
105  /// Get the status of the file.
106  virtual llvm::ErrorOr<Status> status() = 0;
107 
108  /// Get the name of the file
110  if (auto Status = status())
111  return Status->getName().str();
112  else
113  return Status.getError();
114  }
115 
116  /// Get the contents of the file as a \p MemoryBuffer.
118  getBuffer(const Twine &Name, int64_t FileSize = -1,
119  bool RequiresNullTerminator = true, bool IsVolatile = false) = 0;
120 
121  /// Closes the file.
122  virtual std::error_code close() = 0;
123 };
124 
125 /// A member of a directory, yielded by a directory_iterator.
126 /// Only information available on most platforms is included.
128  std::string Path;
130 
131 public:
132  directory_entry() = default;
134  : Path(std::move(Path)), Type(Type) {}
135 
136  llvm::StringRef path() const { return Path; }
137  llvm::sys::fs::file_type type() const { return Type; }
138 };
139 
140 namespace detail {
141 
142 /// An interface for virtual file systems to provide an iterator over the
143 /// (non-recursive) contents of a directory.
144 struct DirIterImpl {
145  virtual ~DirIterImpl();
146 
147  /// Sets \c CurrentEntry to the next entry in the directory on success,
148  /// to directory_entry() at end, or returns a system-defined \c error_code.
149  virtual std::error_code increment() = 0;
150 
152 };
153 
154 } // namespace detail
155 
156 /// An input iterator over the entries in a virtual path, similar to
157 /// llvm::sys::fs::directory_iterator.
159  std::shared_ptr<detail::DirIterImpl> Impl; // Input iterator semantics on copy
160 
161 public:
162  directory_iterator(std::shared_ptr<detail::DirIterImpl> I)
163  : Impl(std::move(I)) {
164  assert(Impl.get() != nullptr && "requires non-null implementation");
165  if (Impl->CurrentEntry.path().empty())
166  Impl.reset(); // Normalize the end iterator to Impl == nullptr.
167  }
168 
169  /// Construct an 'end' iterator.
170  directory_iterator() = default;
171 
172  /// Equivalent to operator++, with an error code.
173  directory_iterator &increment(std::error_code &EC) {
174  assert(Impl && "attempting to increment past end");
175  EC = Impl->increment();
176  if (Impl->CurrentEntry.path().empty())
177  Impl.reset(); // Normalize the end iterator to Impl == nullptr.
178  return *this;
179  }
180 
181  const directory_entry &operator*() const { return Impl->CurrentEntry; }
182  const directory_entry *operator->() const { return &Impl->CurrentEntry; }
183 
184  bool operator==(const directory_iterator &RHS) const {
185  if (Impl && RHS.Impl)
186  return Impl->CurrentEntry.path() == RHS.Impl->CurrentEntry.path();
187  return !Impl && !RHS.Impl;
188  }
189  bool operator!=(const directory_iterator &RHS) const {
190  return !(*this == RHS);
191  }
192 };
193 
194 class FileSystem;
195 
196 namespace detail {
197 
198 /// Keeps state for the recursive_directory_iterator.
200  std::stack<directory_iterator, std::vector<directory_iterator>> Stack;
201  bool HasNoPushRequest = false;
202 };
203 
204 } // end namespace detail
205 
206 /// An input iterator over the recursive contents of a virtual path,
207 /// similar to llvm::sys::fs::recursive_directory_iterator.
209  FileSystem *FS;
210  std::shared_ptr<detail::RecDirIterState>
211  State; // Input iterator semantics on copy.
212 
213 public:
215  std::error_code &EC);
216 
217  /// Construct an 'end' iterator.
218  recursive_directory_iterator() = default;
219 
220  /// Equivalent to operator++, with an error code.
221  recursive_directory_iterator &increment(std::error_code &EC);
222 
223  const directory_entry &operator*() const { return *State->Stack.top(); }
224  const directory_entry *operator->() const { return &*State->Stack.top(); }
225 
226  bool operator==(const recursive_directory_iterator &Other) const {
227  return State == Other.State; // identity
228  }
229  bool operator!=(const recursive_directory_iterator &RHS) const {
230  return !(*this == RHS);
231  }
232 
233  /// Gets the current level. Starting path is at level 0.
234  int level() const {
235  assert(!State->Stack.empty() &&
236  "Cannot get level without any iteration state");
237  return State->Stack.size() - 1;
238  }
239 
240  void no_push() { State->HasNoPushRequest = true; }
241 };
242 
243 /// The virtual file system interface.
244 class FileSystem : public llvm::ThreadSafeRefCountedBase<FileSystem> {
245 public:
246  virtual ~FileSystem();
247 
248  /// Get the status of the entry at \p Path, if one exists.
249  virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0;
250 
251  /// Get a \p File object for the file at \p Path, if one exists.
253  openFileForRead(const Twine &Path) = 0;
254 
255  /// This is a convenience method that opens a file, gets its content and then
256  /// closes the file.
258  getBufferForFile(const Twine &Name, int64_t FileSize = -1,
259  bool RequiresNullTerminator = true, bool IsVolatile = false);
260 
261  /// Get a directory_iterator for \p Dir.
262  /// \note The 'end' iterator is directory_iterator().
263  virtual directory_iterator dir_begin(const Twine &Dir,
264  std::error_code &EC) = 0;
265 
266  /// Set the working directory. This will affect all following operations on
267  /// this file system and may propagate down for nested file systems.
268  virtual std::error_code setCurrentWorkingDirectory(const Twine &Path) = 0;
269 
270  /// Get the working directory of this file system.
271  virtual llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const = 0;
272 
273  /// Gets real path of \p Path e.g. collapse all . and .. patterns, resolve
274  /// symlinks. For real file system, this uses `llvm::sys::fs::real_path`.
275  /// This returns errc::operation_not_permitted if not implemented by subclass.
276  virtual std::error_code getRealPath(const Twine &Path,
277  SmallVectorImpl<char> &Output) const;
278 
279  /// Check whether a file exists. Provided for convenience.
280  bool exists(const Twine &Path);
281 
282  /// Is the file mounted on a local filesystem?
283  virtual std::error_code isLocal(const Twine &Path, bool &Result);
284 
285  /// Make \a Path an absolute path.
286  ///
287  /// Makes \a Path absolute using the current directory if it is not already.
288  /// An empty \a Path will result in the current directory.
289  ///
290  /// /absolute/path => /absolute/path
291  /// relative/../path => <current-directory>/relative/../path
292  ///
293  /// \param Path A path that is modified to be an absolute path.
294  /// \returns success if \a path has been made absolute, otherwise a
295  /// platform-specific error_code.
296  std::error_code makeAbsolute(SmallVectorImpl<char> &Path) const;
297 };
298 
299 /// Gets an \p vfs::FileSystem for the 'real' file system, as seen by
300 /// the operating system.
302 
303 /// A file system that allows overlaying one \p AbstractFileSystem on top
304 /// of another.
305 ///
306 /// Consists of a stack of >=1 \p FileSystem objects, which are treated as being
307 /// one merged file system. When there is a directory that exists in more than
308 /// one file system, the \p OverlayFileSystem contains a directory containing
309 /// the union of their contents. The attributes (permissions, etc.) of the
310 /// top-most (most recently added) directory are used. When there is a file
311 /// that exists in more than one file system, the file in the top-most file
312 /// system overrides the other(s).
315 
316  /// The stack of file systems, implemented as a list in order of
317  /// their addition.
318  FileSystemList FSList;
319 
320 public:
322 
323  /// Pushes a file system on top of the stack.
324  void pushOverlay(IntrusiveRefCntPtr<FileSystem> FS);
325 
326  llvm::ErrorOr<Status> status(const Twine &Path) override;
328  openFileForRead(const Twine &Path) override;
329  directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
330  llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override;
331  std::error_code setCurrentWorkingDirectory(const Twine &Path) override;
332  std::error_code isLocal(const Twine &Path, bool &Result) override;
333  std::error_code getRealPath(const Twine &Path,
334  SmallVectorImpl<char> &Output) const override;
335 
338 
339  /// Get an iterator pointing to the most recently added file system.
340  iterator overlays_begin() { return FSList.rbegin(); }
341  const_iterator overlays_begin() const { return FSList.rbegin(); }
342 
343  /// Get an iterator pointing one-past the least recently added file
344  /// system.
345  iterator overlays_end() { return FSList.rend(); }
346  const_iterator overlays_end() const { return FSList.rend(); }
347 };
348 
349 /// By default, this delegates all calls to the underlying file system. This
350 /// is useful when derived file systems want to override some calls and still
351 /// proxy other calls.
352 class ProxyFileSystem : public FileSystem {
353 public:
355  : FS(std::move(FS)) {}
356 
357  llvm::ErrorOr<Status> status(const Twine &Path) override {
358  return FS->status(Path);
359  }
361  openFileForRead(const Twine &Path) override {
362  return FS->openFileForRead(Path);
363  }
364  directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override {
365  return FS->dir_begin(Dir, EC);
366  }
368  return FS->getCurrentWorkingDirectory();
369  }
370  std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
371  return FS->setCurrentWorkingDirectory(Path);
372  }
373  std::error_code getRealPath(const Twine &Path,
374  SmallVectorImpl<char> &Output) const override {
375  return FS->getRealPath(Path, Output);
376  }
377  std::error_code isLocal(const Twine &Path, bool &Result) override {
378  return FS->isLocal(Path, Result);
379  }
380 
381 protected:
382  FileSystem &getUnderlyingFS() { return *FS; }
383 
384 private:
386 
387  virtual void anchor();
388 };
389 
390 namespace detail {
391 
392 class InMemoryDirectory;
393 class InMemoryFile;
394 
395 } // namespace detail
396 
397 /// An in-memory file system.
399  std::unique_ptr<detail::InMemoryDirectory> Root;
400  std::string WorkingDirectory;
401  bool UseNormalizedPaths = true;
402 
403  /// If HardLinkTarget is non-null, a hardlink is created to the To path which
404  /// must be a file. If it is null then it adds the file as the public addFile.
405  bool addFile(const Twine &Path, time_t ModificationTime,
406  std::unique_ptr<llvm::MemoryBuffer> Buffer,
410  const detail::InMemoryFile *HardLinkTarget);
411 
412 public:
413  explicit InMemoryFileSystem(bool UseNormalizedPaths = true);
414  ~InMemoryFileSystem() override;
415 
416  /// Add a file containing a buffer or a directory to the VFS with a
417  /// path. The VFS owns the buffer. If present, User, Group, Type
418  /// and Perms apply to the newly-created file or directory.
419  /// \return true if the file or directory was successfully added,
420  /// false if the file or directory already exists in the file system with
421  /// different contents.
422  bool addFile(const Twine &Path, time_t ModificationTime,
423  std::unique_ptr<llvm::MemoryBuffer> Buffer,
427 
428  /// Add a hard link to a file.
429  /// Here hard links are not intended to be fully equivalent to the classical
430  /// filesystem. Both the hard link and the file share the same buffer and
431  /// status (and thus have the same UniqueID). Because of this there is no way
432  /// to distinguish between the link and the file after the link has been
433  /// added.
434  ///
435  /// The To path must be an existing file or a hardlink. The From file must not
436  /// have been added before. The To Path must not be a directory. The From Node
437  /// is added as a hard link which points to the resolved file of To Node.
438  /// \return true if the above condition is satisfied and hardlink was
439  /// successfully created, false otherwise.
440  bool addHardLink(const Twine &From, const Twine &To);
441 
442  /// Add a buffer to the VFS with a path. The VFS does not own the buffer.
443  /// If present, User, Group, Type and Perms apply to the newly-created file
444  /// or directory.
445  /// \return true if the file or directory was successfully added,
446  /// false if the file or directory already exists in the file system with
447  /// different contents.
448  bool addFileNoOwn(const Twine &Path, time_t ModificationTime,
450  Optional<uint32_t> Group = None,
453 
454  std::string toString() const;
455 
456  /// Return true if this file system normalizes . and .. in paths.
457  bool useNormalizedPaths() const { return UseNormalizedPaths; }
458 
459  llvm::ErrorOr<Status> status(const Twine &Path) override;
461  openFileForRead(const Twine &Path) override;
462  directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
463 
465  return WorkingDirectory;
466  }
467  /// Canonicalizes \p Path by combining with the current working
468  /// directory and normalizing the path (e.g. remove dots). If the current
469  /// working directory is not set, this returns errc::operation_not_permitted.
470  ///
471  /// This doesn't resolve symlinks as they are not supported in in-memory file
472  /// system.
473  std::error_code getRealPath(const Twine &Path,
474  SmallVectorImpl<char> &Output) const override;
475  std::error_code isLocal(const Twine &Path, bool &Result) override;
476  std::error_code setCurrentWorkingDirectory(const Twine &Path) override;
477 };
478 
479 /// Get a globally unique ID for a virtual file or directory.
481 
482 /// Gets a \p FileSystem for a virtual file system described in YAML
483 /// format.
485 getVFSFromYAML(std::unique_ptr<llvm::MemoryBuffer> Buffer,
486  llvm::SourceMgr::DiagHandlerTy DiagHandler,
487  StringRef YAMLFilePath, void *DiagContext = nullptr,
489 
490 struct YAMLVFSEntry {
491  template <typename T1, typename T2>
492  YAMLVFSEntry(T1 &&VPath, T2 &&RPath)
493  : VPath(std::forward<T1>(VPath)), RPath(std::forward<T2>(RPath)) {}
494  std::string VPath;
495  std::string RPath;
496 };
497 
500 
501 /// A virtual file system parsed from a YAML file.
502 ///
503 /// Currently, this class allows creating virtual directories and mapping
504 /// virtual file paths to existing external files, available in \c ExternalFS.
505 ///
506 /// The basic structure of the parsed file is:
507 /// \verbatim
508 /// {
509 /// 'version': <version number>,
510 /// <optional configuration>
511 /// 'roots': [
512 /// <directory entries>
513 /// ]
514 /// }
515 /// \endverbatim
516 ///
517 /// All configuration options are optional.
518 /// 'case-sensitive': <boolean, default=true>
519 /// 'use-external-names': <boolean, default=true>
520 /// 'overlay-relative': <boolean, default=false>
521 /// 'fallthrough': <boolean, default=true>
522 ///
523 /// Virtual directories are represented as
524 /// \verbatim
525 /// {
526 /// 'type': 'directory',
527 /// 'name': <string>,
528 /// 'contents': [ <file or directory entries> ]
529 /// }
530 /// \endverbatim
531 ///
532 /// The default attributes for virtual directories are:
533 /// \verbatim
534 /// MTime = now() when created
535 /// Perms = 0777
536 /// User = Group = 0
537 /// Size = 0
538 /// UniqueID = unspecified unique value
539 /// \endverbatim
540 ///
541 /// Re-mapped files are represented as
542 /// \verbatim
543 /// {
544 /// 'type': 'file',
545 /// 'name': <string>,
546 /// 'use-external-name': <boolean> # Optional
547 /// 'external-contents': <path to external file>
548 /// }
549 /// \endverbatim
550 ///
551 /// and inherit their attributes from the external contents.
552 ///
553 /// In both cases, the 'name' field may contain multiple path components (e.g.
554 /// /path/to/file). However, any directory that contains more than one child
555 /// must be uniquely represented by a directory entry.
557 public:
558  enum EntryKind { EK_Directory, EK_File };
559 
560  /// A single file or directory in the VFS.
561  class Entry {
562  EntryKind Kind;
563  std::string Name;
564 
565  public:
566  Entry(EntryKind K, StringRef Name) : Kind(K), Name(Name) {}
567  virtual ~Entry() = default;
568 
569  StringRef getName() const { return Name; }
570  EntryKind getKind() const { return Kind; }
571  };
572 
574  std::vector<std::unique_ptr<Entry>> Contents;
575  Status S;
576 
577  public:
579  std::vector<std::unique_ptr<Entry>> Contents,
580  Status S)
581  : Entry(EK_Directory, Name), Contents(std::move(Contents)),
582  S(std::move(S)) {}
584  : Entry(EK_Directory, Name), S(std::move(S)) {}
585 
586  Status getStatus() { return S; }
587 
588  void addContent(std::unique_ptr<Entry> Content) {
589  Contents.push_back(std::move(Content));
590  }
591 
592  Entry *getLastContent() const { return Contents.back().get(); }
593 
594  using iterator = decltype(Contents)::iterator;
595 
596  iterator contents_begin() { return Contents.begin(); }
597  iterator contents_end() { return Contents.end(); }
598 
599  static bool classof(const Entry *E) { return E->getKind() == EK_Directory; }
600  };
601 
602  class RedirectingFileEntry : public Entry {
603  public:
604  enum NameKind { NK_NotSet, NK_External, NK_Virtual };
605 
606  private:
607  std::string ExternalContentsPath;
608  NameKind UseName;
609 
610  public:
611  RedirectingFileEntry(StringRef Name, StringRef ExternalContentsPath,
612  NameKind UseName)
613  : Entry(EK_File, Name), ExternalContentsPath(ExternalContentsPath),
614  UseName(UseName) {}
615 
616  StringRef getExternalContentsPath() const { return ExternalContentsPath; }
617 
618  /// whether to use the external path as the name for this file.
619  bool useExternalName(bool GlobalUseExternalName) const {
620  return UseName == NK_NotSet ? GlobalUseExternalName
621  : (UseName == NK_External);
622  }
623 
624  NameKind getUseName() const { return UseName; }
625 
626  static bool classof(const Entry *E) { return E->getKind() == EK_File; }
627  };
628 
629 private:
632 
633  /// The root(s) of the virtual file system.
634  std::vector<std::unique_ptr<Entry>> Roots;
635 
636  /// The file system to use for external references.
638 
639  /// If IsRelativeOverlay is set, this represents the directory
640  /// path that should be prefixed to each 'external-contents' entry
641  /// when reading from YAML files.
642  std::string ExternalContentsPrefixDir;
643 
644  /// @name Configuration
645  /// @{
646 
647  /// Whether to perform case-sensitive comparisons.
648  ///
649  /// Currently, case-insensitive matching only works correctly with ASCII.
650  bool CaseSensitive = true;
651 
652  /// IsRelativeOverlay marks whether a ExternalContentsPrefixDir path must
653  /// be prefixed in every 'external-contents' when reading from YAML files.
654  bool IsRelativeOverlay = false;
655 
656  /// Whether to use to use the value of 'external-contents' for the
657  /// names of files. This global value is overridable on a per-file basis.
658  bool UseExternalNames = true;
659 
660  /// Whether to attempt a file lookup in external file system after it wasn't
661  /// found in VFS.
662  bool IsFallthrough = true;
663  /// @}
664 
665  /// Virtual file paths and external files could be canonicalized without "..",
666  /// "." and "./" in their paths. FIXME: some unittests currently fail on
667  /// win32 when using remove_dots and remove_leading_dotslash on paths.
668  bool UseCanonicalizedPaths =
669 #ifdef _WIN32
670  false;
671 #else
672  true;
673 #endif
674 
676  : ExternalFS(std::move(ExternalFS)) {}
677 
678  /// Looks up the path <tt>[Start, End)</tt> in \p From, possibly
679  /// recursing into the contents of \p From if it is a directory.
682  Entry *From) const;
683 
684  /// Get the status of a given an \c Entry.
685  ErrorOr<Status> status(const Twine &Path, Entry *E);
686 
687 public:
688  /// Looks up \p Path in \c Roots.
689  ErrorOr<Entry *> lookupPath(const Twine &Path) const;
690 
691  /// Parses \p Buffer, which is expected to be in YAML format and
692  /// returns a virtual file system representing its contents.
693  static RedirectingFileSystem *
694  create(std::unique_ptr<MemoryBuffer> Buffer,
695  SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath,
696  void *DiagContext, IntrusiveRefCntPtr<FileSystem> ExternalFS);
697 
698  ErrorOr<Status> status(const Twine &Path) override;
699  ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override;
700 
701  std::error_code getRealPath(const Twine &Path,
702  SmallVectorImpl<char> &Output) const override;
703 
704  llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override;
705 
706  std::error_code setCurrentWorkingDirectory(const Twine &Path) override;
707 
708  std::error_code isLocal(const Twine &Path, bool &Result) override;
709 
710  directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
711 
712  void setExternalContentsPrefixDir(StringRef PrefixDir);
713 
714  StringRef getExternalContentsPrefixDir() const;
715 
716 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
717  LLVM_DUMP_METHOD void dump() const;
718  LLVM_DUMP_METHOD void dumpEntry(Entry *E, int NumSpaces = 0) const;
719 #endif
720 };
721 
722 /// Collect all pairs of <virtual path, real path> entries from the
723 /// \p YAMLFilePath. This is used by the module dependency collector to forward
724 /// the entries into the reproducer output VFS YAML file.
725 void collectVFSFromYAML(
726  std::unique_ptr<llvm::MemoryBuffer> Buffer,
727  llvm::SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath,
728  SmallVectorImpl<YAMLVFSEntry> &CollectedEntries,
729  void *DiagContext = nullptr,
731 
733  std::vector<YAMLVFSEntry> Mappings;
734  Optional<bool> IsCaseSensitive;
735  Optional<bool> IsOverlayRelative;
736  Optional<bool> UseExternalNames;
737  std::string OverlayDir;
738 
739 public:
740  YAMLVFSWriter() = default;
741 
742  void addFileMapping(StringRef VirtualPath, StringRef RealPath);
743 
744  void setCaseSensitivity(bool CaseSensitive) {
745  IsCaseSensitive = CaseSensitive;
746  }
747 
748  void setUseExternalNames(bool UseExtNames) { UseExternalNames = UseExtNames; }
749 
750  void setOverlayDir(StringRef OverlayDirectory) {
751  IsOverlayRelative = true;
752  OverlayDir.assign(OverlayDirectory.str());
753  }
754 
755  const std::vector<YAMLVFSEntry> &getMappings() const { return Mappings; }
756 
757  void write(llvm::raw_ostream &OS);
758 };
759 
760 } // namespace vfs
761 } // namespace llvm
762 
763 #endif // LLVM_SUPPORT_VIRTUALFILESYSTEM_H
An input iterator over the recursive contents of a virtual path, similar to llvm::sys::fs::recursive_...
const NoneType None
Definition: None.h:23
const directory_entry * operator->() const
const directory_entry & operator*() const
A file system that allows overlaying one AbstractFileSystem on top of another.
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: SmallVector.h:118
iterator overlays_begin()
Get an iterator pointing to the most recently added file system.
An interface for virtual file systems to provide an iterator over the (non-recursive) contents of a d...
llvm::StringRef path() const
Represents either an error or a value T.
Definition: ErrorOr.h:56
RedirectingDirectoryEntry(StringRef Name, std::vector< std::unique_ptr< Entry >> Contents, Status S)
const directory_entry & operator*() const
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:218
bool operator==(const directory_iterator &RHS) const
IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the &#39;real&#39; file system, as seen by the operating system.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
std::error_code openFileForRead(const Twine &Name, int &ResultFD, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
Definition: Compiler.h:464
ProxyFileSystem(IntrusiveRefCntPtr< FileSystem > FS)
FileSystemList::reverse_iterator iterator
constexpr char IsVolatile[]
Key for Kernel::Arg::Metadata::mIsVolatile.
llvm::ErrorOr< std::string > getCurrentWorkingDirectory() const override
Get the working directory of this file system.
llvm::sys::fs::UniqueID getNextVirtualUniqueID()
Get a globally unique ID for a virtual file or directory.
YAMLVFSEntry(T1 &&VPath, T2 &&RPath)
directory_entry(std::string Path, llvm::sys::fs::file_type Type)
uint32_t getUser() const
const std::vector< YAMLVFSEntry > & getMappings() const
llvm::sys::fs::file_type type() const
The result of a status operation.
FileSystemList::const_reverse_iterator const_iterator
Entry(EntryKind K, StringRef Name)
Represents the result of a call to sys::fs::status().
Definition: FileSystem.h:246
Represents an open file.
bool useExternalName(bool GlobalUseExternalName) const
whether to use the external path as the name for this file.
int level() const
Gets the current level. Starting path is at level 0.
llvm::ErrorOr< std::unique_ptr< File > > openFileForRead(const Twine &Path) override
Get a File object for the file at Path, if one exists.
directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override
Get a directory_iterator for Dir.
Definition: BitVector.h:937
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:966
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
StringRef getName() const
Returns the name that should be used for this file or directory.
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:783
const_iterator overlays_begin() const
void setCaseSensitivity(bool CaseSensitive)
bool operator==(const recursive_directory_iterator &Other) const
RedirectingFileEntry(StringRef Name, StringRef ExternalContentsPath, NameKind UseName)
directory_iterator & increment(std::error_code &EC)
Equivalent to operator++, with an error code.
llvm::sys::fs::file_type getType() const
llvm::sys::TimePoint getLastModificationTime() const
bool isRegularFile() const
A virtual file system parsed from a YAML file.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::sys::fs::perms getPermissions() const
std::reverse_iterator< iterator > reverse_iterator
Definition: SmallVector.h:119
A single file or directory in the VFS.
Keeps state for the recursive_directory_iterator.
std::error_code getRealPath(const Twine &Path, SmallVectorImpl< char > &Output) const override
Gets real path of Path e.g.
void(*)(const SMDiagnostic &, void *Context) DiagHandlerTy
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
Definition: SourceMgr.h:53
By default, this delegates all calls to the underlying file system.
static void write(bool isBE, void *P, T V)
bool isStatusKnown() const
static Status copyWithNewName(const Status &In, StringRef NewName)
Get a copy of a Status with a different name.
std::error_code isLocal(const Twine &Path, bool &Result) override
Is the file mounted on a local filesystem?
A member of a directory, yielded by a directory_iterator.
virtual llvm::ErrorOr< std::string > getName()
Get the name of the file.
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
uint64_t getSize() const
std::error_code setCurrentWorkingDirectory(const Twine &Path) override
Set the working directory.
bool useNormalizedPaths() const
Return true if this file system normalizes . and .. in paths.
BlockVerifier::State From
An input iterator over the entries in a virtual path, similar to llvm::sys::fs::directory_iterator.
bool equivalent(const Status &Other) const
void setUseExternalNames(bool UseExtNames)
The virtual file system interface.
const directory_entry * operator->() const
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:41
uint32_t getGroup() const
A thread-safe version of RefCountedBase.
An in-memory file system.
Path iterator.
Definition: Path.h:52
bool operator!=(const directory_iterator &RHS) const
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.
file_type
An enumeration for the file system&#39;s view of the type.
Definition: FileSystem.h:66
#define I(x, y, z)
Definition: MD5.cpp:58
bool isDirectory() const
Provides ErrorOr<T> smart pointer.
const unsigned Kind
std::stack< directory_iterator, std::vector< directory_iterator > > Stack
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A helper class to hold the common YAML parsing state.
llvm::ErrorOr< std::string > getCurrentWorkingDirectory() const override
Get the working directory of this file system.
llvm::sys::fs::UniqueID getUniqueID() const
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
bool operator!=(const recursive_directory_iterator &RHS) const
void setOverlayDir(StringRef OverlayDirectory)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
const_iterator overlays_end() const
iterator overlays_end()
Get an iterator pointing one-past the least recently added file system.
#define T1
directory_iterator(std::shared_ptr< detail::DirIterImpl > I)
std::chrono::time_point< std::chrono::system_clock, D > TimePoint
A time point on the system clock.
Definition: Chrono.h:33
llvm::ErrorOr< Status > status(const Twine &Path) override
Get the status of the entry at Path, if one exists.