Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:49

0001 //===--- FileManager.h - File System Probing and Caching --------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// Defines the clang::FileManager interface and associated types.
0011 ///
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_BASIC_FILEMANAGER_H
0015 #define LLVM_CLANG_BASIC_FILEMANAGER_H
0016 
0017 #include "clang/Basic/DirectoryEntry.h"
0018 #include "clang/Basic/FileEntry.h"
0019 #include "clang/Basic/FileSystemOptions.h"
0020 #include "clang/Basic/LLVM.h"
0021 #include "llvm/ADT/DenseMap.h"
0022 #include "llvm/ADT/IntrusiveRefCntPtr.h"
0023 #include "llvm/ADT/PointerUnion.h"
0024 #include "llvm/ADT/SmallVector.h"
0025 #include "llvm/ADT/StringMap.h"
0026 #include "llvm/ADT/StringRef.h"
0027 #include "llvm/Support/Allocator.h"
0028 #include "llvm/Support/ErrorOr.h"
0029 #include "llvm/Support/FileSystem.h"
0030 #include "llvm/Support/VirtualFileSystem.h"
0031 #include <ctime>
0032 #include <map>
0033 #include <memory>
0034 #include <string>
0035 
0036 namespace llvm {
0037 
0038 class MemoryBuffer;
0039 
0040 } // end namespace llvm
0041 
0042 namespace clang {
0043 
0044 class FileSystemStatCache;
0045 
0046 /// Implements support for file system lookup, file system caching,
0047 /// and directory search management.
0048 ///
0049 /// This also handles more advanced properties, such as uniquing files based
0050 /// on "inode", so that a file with two names (e.g. symlinked) will be treated
0051 /// as a single file.
0052 ///
0053 class FileManager : public RefCountedBase<FileManager> {
0054   IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
0055   FileSystemOptions FileSystemOpts;
0056   llvm::SpecificBumpPtrAllocator<FileEntry> FilesAlloc;
0057   llvm::SpecificBumpPtrAllocator<DirectoryEntry> DirsAlloc;
0058 
0059   /// Cache for existing real directories.
0060   llvm::DenseMap<llvm::sys::fs::UniqueID, DirectoryEntry *> UniqueRealDirs;
0061 
0062   /// Cache for existing real files.
0063   llvm::DenseMap<llvm::sys::fs::UniqueID, FileEntry *> UniqueRealFiles;
0064 
0065   /// The virtual directories that we have allocated.
0066   ///
0067   /// For each virtual file (e.g. foo/bar/baz.cpp), we add all of its parent
0068   /// directories (foo/ and foo/bar/) here.
0069   SmallVector<DirectoryEntry *, 4> VirtualDirectoryEntries;
0070   /// The virtual files that we have allocated.
0071   SmallVector<FileEntry *, 4> VirtualFileEntries;
0072 
0073   /// A set of files that bypass the maps and uniquing.  They can have
0074   /// conflicting filenames.
0075   SmallVector<FileEntry *, 0> BypassFileEntries;
0076 
0077   /// A cache that maps paths to directory entries (either real or
0078   /// virtual) we have looked up, or an error that occurred when we looked up
0079   /// the directory.
0080   ///
0081   /// The actual Entries for real directories/files are
0082   /// owned by UniqueRealDirs/UniqueRealFiles above, while the Entries
0083   /// for virtual directories/files are owned by
0084   /// VirtualDirectoryEntries/VirtualFileEntries above.
0085   ///
0086   llvm::StringMap<llvm::ErrorOr<DirectoryEntry &>, llvm::BumpPtrAllocator>
0087       SeenDirEntries;
0088 
0089   /// A cache that maps paths to file entries (either real or
0090   /// virtual) we have looked up, or an error that occurred when we looked up
0091   /// the file.
0092   ///
0093   /// \see SeenDirEntries
0094   llvm::StringMap<llvm::ErrorOr<FileEntryRef::MapValue>, llvm::BumpPtrAllocator>
0095       SeenFileEntries;
0096 
0097   /// A mirror of SeenFileEntries to give fake answers for getBypassFile().
0098   ///
0099   /// Don't bother hooking up a BumpPtrAllocator. This should be rarely used,
0100   /// and only on error paths.
0101   std::unique_ptr<llvm::StringMap<llvm::ErrorOr<FileEntryRef::MapValue>>>
0102       SeenBypassFileEntries;
0103 
0104   /// The file entry for stdin, if it has been accessed through the FileManager.
0105   OptionalFileEntryRef STDIN;
0106 
0107   /// The canonical names of files and directories .
0108   llvm::DenseMap<const void *, llvm::StringRef> CanonicalNames;
0109 
0110   /// Storage for canonical names that we have computed.
0111   llvm::BumpPtrAllocator CanonicalNameStorage;
0112 
0113   /// Each FileEntry we create is assigned a unique ID #.
0114   ///
0115   unsigned NextFileUID;
0116 
0117   /// Statistics gathered during the lifetime of the FileManager.
0118   unsigned NumDirLookups = 0;
0119   unsigned NumFileLookups = 0;
0120   unsigned NumDirCacheMisses = 0;
0121   unsigned NumFileCacheMisses = 0;
0122 
0123   // Caching.
0124   std::unique_ptr<FileSystemStatCache> StatCache;
0125 
0126   std::error_code getStatValue(StringRef Path, llvm::vfs::Status &Status,
0127                                bool isFile, std::unique_ptr<llvm::vfs::File> *F,
0128                                bool IsText = true);
0129 
0130   /// Add all ancestors of the given path (pointing to either a file
0131   /// or a directory) as virtual directories.
0132   void addAncestorsAsVirtualDirs(StringRef Path);
0133 
0134   /// Fills the RealPathName in file entry.
0135   void fillRealPathName(FileEntry *UFE, llvm::StringRef FileName);
0136 
0137 public:
0138   /// Construct a file manager, optionally with a custom VFS.
0139   ///
0140   /// \param FS if non-null, the VFS to use.  Otherwise uses
0141   /// llvm::vfs::getRealFileSystem().
0142   FileManager(const FileSystemOptions &FileSystemOpts,
0143               IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr);
0144   ~FileManager();
0145 
0146   /// Installs the provided FileSystemStatCache object within
0147   /// the FileManager.
0148   ///
0149   /// Ownership of this object is transferred to the FileManager.
0150   ///
0151   /// \param statCache the new stat cache to install. Ownership of this
0152   /// object is transferred to the FileManager.
0153   void setStatCache(std::unique_ptr<FileSystemStatCache> statCache);
0154 
0155   /// Removes the FileSystemStatCache object from the manager.
0156   void clearStatCache();
0157 
0158   /// Returns the number of unique real file entries cached by the file manager.
0159   size_t getNumUniqueRealFiles() const { return UniqueRealFiles.size(); }
0160 
0161   /// Lookup, cache, and verify the specified directory (real or
0162   /// virtual).
0163   ///
0164   /// This returns a \c std::error_code if there was an error reading the
0165   /// directory. On success, returns the reference to the directory entry
0166   /// together with the exact path that was used to access a file by a
0167   /// particular call to getDirectoryRef.
0168   ///
0169   /// \param CacheFailure If true and the file does not exist, we'll cache
0170   /// the failure to find this file.
0171   llvm::Expected<DirectoryEntryRef> getDirectoryRef(StringRef DirName,
0172                                                     bool CacheFailure = true);
0173 
0174   /// Get a \c DirectoryEntryRef if it exists, without doing anything on error.
0175   OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName,
0176                                                     bool CacheFailure = true) {
0177     return llvm::expectedToOptional(getDirectoryRef(DirName, CacheFailure));
0178   }
0179 
0180   /// Lookup, cache, and verify the specified directory (real or
0181   /// virtual).
0182   ///
0183   /// This function is deprecated and will be removed at some point in the
0184   /// future, new clients should use
0185   ///  \c getDirectoryRef.
0186   ///
0187   /// This returns a \c std::error_code if there was an error reading the
0188   /// directory. If there is no error, the DirectoryEntry is guaranteed to be
0189   /// non-NULL.
0190   ///
0191   /// \param CacheFailure If true and the file does not exist, we'll cache
0192   /// the failure to find this file.
0193   LLVM_DEPRECATED("Functions returning DirectoryEntry are deprecated.",
0194                   "getOptionalDirectoryRef()")
0195   llvm::ErrorOr<const DirectoryEntry *>
0196   getDirectory(StringRef DirName, bool CacheFailure = true);
0197 
0198   /// Lookup, cache, and verify the specified file (real or
0199   /// virtual).
0200   ///
0201   /// This function is deprecated and will be removed at some point in the
0202   /// future, new clients should use
0203   ///  \c getFileRef.
0204   ///
0205   /// This returns a \c std::error_code if there was an error loading the file.
0206   /// If there is no error, the FileEntry is guaranteed to be non-NULL.
0207   ///
0208   /// \param OpenFile if true and the file exists, it will be opened.
0209   ///
0210   /// \param CacheFailure If true and the file does not exist, we'll cache
0211   /// the failure to find this file.
0212   LLVM_DEPRECATED("Functions returning FileEntry are deprecated.",
0213                   "getOptionalFileRef()")
0214   llvm::ErrorOr<const FileEntry *>
0215   getFile(StringRef Filename, bool OpenFile = false, bool CacheFailure = true);
0216 
0217   /// Lookup, cache, and verify the specified file (real or virtual). Return the
0218   /// reference to the file entry together with the exact path that was used to
0219   /// access a file by a particular call to getFileRef. If the underlying VFS is
0220   /// a redirecting VFS that uses external file names, the returned FileEntryRef
0221   /// will use the external name instead of the filename that was passed to this
0222   /// method.
0223   ///
0224   /// This returns a \c std::error_code if there was an error loading the file,
0225   /// or a \c FileEntryRef otherwise.
0226   ///
0227   /// \param OpenFile if true and the file exists, it will be opened.
0228   ///
0229   /// \param CacheFailure If true and the file does not exist, we'll cache
0230   /// the failure to find this file.
0231   llvm::Expected<FileEntryRef> getFileRef(StringRef Filename,
0232                                           bool OpenFile = false,
0233                                           bool CacheFailure = true,
0234                                           bool IsText = true);
0235 
0236   /// Get the FileEntryRef for stdin, returning an error if stdin cannot be
0237   /// read.
0238   ///
0239   /// This reads and caches stdin before returning. Subsequent calls return the
0240   /// same file entry, and a reference to the cached input is returned by calls
0241   /// to getBufferForFile.
0242   llvm::Expected<FileEntryRef> getSTDIN();
0243 
0244   /// Get a FileEntryRef if it exists, without doing anything on error.
0245   OptionalFileEntryRef getOptionalFileRef(StringRef Filename,
0246                                           bool OpenFile = false,
0247                                           bool CacheFailure = true) {
0248     return llvm::expectedToOptional(
0249         getFileRef(Filename, OpenFile, CacheFailure));
0250   }
0251 
0252   /// Returns the current file system options
0253   FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
0254   const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
0255 
0256   llvm::vfs::FileSystem &getVirtualFileSystem() const { return *FS; }
0257   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
0258   getVirtualFileSystemPtr() const {
0259     return FS;
0260   }
0261 
0262   /// Enable or disable tracking of VFS usage. Used to not track full header
0263   /// search and implicit modulemap lookup.
0264   void trackVFSUsage(bool Active);
0265 
0266   void setVirtualFileSystem(IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) {
0267     this->FS = std::move(FS);
0268   }
0269 
0270   /// Retrieve a file entry for a "virtual" file that acts as
0271   /// if there were a file with the given name on disk.
0272   ///
0273   /// The file itself is not accessed.
0274   FileEntryRef getVirtualFileRef(StringRef Filename, off_t Size,
0275                                  time_t ModificationTime);
0276 
0277   LLVM_DEPRECATED("Functions returning FileEntry are deprecated.",
0278                   "getVirtualFileRef()")
0279   const FileEntry *getVirtualFile(StringRef Filename, off_t Size,
0280                                   time_t ModificationTime);
0281 
0282   /// Retrieve a FileEntry that bypasses VFE, which is expected to be a virtual
0283   /// file entry, to access the real file.  The returned FileEntry will have
0284   /// the same filename as FE but a different identity and its own stat.
0285   ///
0286   /// This should be used only for rare error recovery paths because it
0287   /// bypasses all mapping and uniquing, blindly creating a new FileEntry.
0288   /// There is no attempt to deduplicate these; if you bypass the same file
0289   /// twice, you get two new file entries.
0290   OptionalFileEntryRef getBypassFile(FileEntryRef VFE);
0291 
0292   /// Open the specified file as a MemoryBuffer, returning a new
0293   /// MemoryBuffer if successful, otherwise returning null.
0294   /// The IsText parameter controls whether the file should be opened as a text
0295   /// or binary file, and should be set to false if the file contents should be
0296   /// treated as binary.
0297   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
0298   getBufferForFile(FileEntryRef Entry, bool isVolatile = false,
0299                    bool RequiresNullTerminator = true,
0300                    std::optional<int64_t> MaybeLimit = std::nullopt,
0301                    bool IsText = true);
0302   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
0303   getBufferForFile(StringRef Filename, bool isVolatile = false,
0304                    bool RequiresNullTerminator = true,
0305                    std::optional<int64_t> MaybeLimit = std::nullopt,
0306                    bool IsText = true) const {
0307     return getBufferForFileImpl(Filename,
0308                                 /*FileSize=*/MaybeLimit.value_or(-1),
0309                                 isVolatile, RequiresNullTerminator, IsText);
0310   }
0311 
0312 private:
0313   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
0314   getBufferForFileImpl(StringRef Filename, int64_t FileSize, bool isVolatile,
0315                        bool RequiresNullTerminator, bool IsText) const;
0316 
0317   DirectoryEntry *&getRealDirEntry(const llvm::vfs::Status &Status);
0318 
0319 public:
0320   /// Get the 'stat' information for the given \p Path.
0321   ///
0322   /// If the path is relative, it will be resolved against the WorkingDir of the
0323   /// FileManager's FileSystemOptions.
0324   ///
0325   /// \returns a \c std::error_code describing an error, if there was one
0326   std::error_code getNoncachedStatValue(StringRef Path,
0327                                         llvm::vfs::Status &Result);
0328 
0329   /// If path is not absolute and FileSystemOptions set the working
0330   /// directory, the path is modified to be relative to the given
0331   /// working directory.
0332   /// \returns true if \c path changed.
0333   bool FixupRelativePath(SmallVectorImpl<char> &path) const;
0334 
0335   /// Makes \c Path absolute taking into account FileSystemOptions and the
0336   /// working directory option.
0337   /// \returns true if \c Path changed to absolute.
0338   bool makeAbsolutePath(SmallVectorImpl<char> &Path) const;
0339 
0340   /// Produce an array mapping from the unique IDs assigned to each
0341   /// file to the corresponding FileEntryRef.
0342   void
0343   GetUniqueIDMapping(SmallVectorImpl<OptionalFileEntryRef> &UIDToFiles) const;
0344 
0345   /// Retrieve the canonical name for a given directory.
0346   ///
0347   /// This is a very expensive operation, despite its results being cached,
0348   /// and should only be used when the physical layout of the file system is
0349   /// required, which is (almost) never.
0350   StringRef getCanonicalName(DirectoryEntryRef Dir);
0351 
0352   /// Retrieve the canonical name for a given file.
0353   ///
0354   /// This is a very expensive operation, despite its results being cached,
0355   /// and should only be used when the physical layout of the file system is
0356   /// required, which is (almost) never.
0357   StringRef getCanonicalName(FileEntryRef File);
0358 
0359 private:
0360   /// Retrieve the canonical name for a given file or directory.
0361   ///
0362   /// The first param is a key in the CanonicalNames array.
0363   StringRef getCanonicalName(const void *Entry, StringRef Name);
0364 
0365 public:
0366   void PrintStats() const;
0367 
0368   /// Import statistics from a child FileManager and add them to this current
0369   /// FileManager.
0370   void AddStats(const FileManager &Other);
0371 };
0372 
0373 } // end namespace clang
0374 
0375 #endif // LLVM_CLANG_BASIC_FILEMANAGER_H