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