|
|
|||
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
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|