clang 20.0.0git
FileManager.h
Go to the documentation of this file.
1//===--- FileManager.h - File System Probing and Caching --------*- 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 clang::FileManager interface and associated types.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_BASIC_FILEMANAGER_H
15#define LLVM_CLANG_BASIC_FILEMANAGER_H
16
20#include "clang/Basic/LLVM.h"
21#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/IntrusiveRefCntPtr.h"
23#include "llvm/ADT/PointerUnion.h"
24#include "llvm/ADT/SmallVector.h"
25#include "llvm/ADT/StringMap.h"
26#include "llvm/ADT/StringRef.h"
27#include "llvm/Support/Allocator.h"
28#include "llvm/Support/ErrorOr.h"
29#include "llvm/Support/FileSystem.h"
30#include "llvm/Support/VirtualFileSystem.h"
31#include <ctime>
32#include <map>
33#include <memory>
34#include <string>
35
36namespace llvm {
37
38class MemoryBuffer;
39
40} // end namespace llvm
41
42namespace clang {
43
44class FileSystemStatCache;
45
46/// Implements support for file system lookup, file system caching,
47/// and directory search management.
48///
49/// This also handles more advanced properties, such as uniquing files based
50/// on "inode", so that a file with two names (e.g. symlinked) will be treated
51/// as a single file.
52///
53class FileManager : public RefCountedBase<FileManager> {
55 FileSystemOptions FileSystemOpts;
56 llvm::SpecificBumpPtrAllocator<FileEntry> FilesAlloc;
57 llvm::SpecificBumpPtrAllocator<DirectoryEntry> DirsAlloc;
58
59 /// Cache for existing real directories.
60 llvm::DenseMap<llvm::sys::fs::UniqueID, DirectoryEntry *> UniqueRealDirs;
61
62 /// Cache for existing real files.
63 llvm::DenseMap<llvm::sys::fs::UniqueID, FileEntry *> UniqueRealFiles;
64
65 /// The virtual directories that we have allocated.
66 ///
67 /// For each virtual file (e.g. foo/bar/baz.cpp), we add all of its parent
68 /// directories (foo/ and foo/bar/) here.
69 SmallVector<DirectoryEntry *, 4> VirtualDirectoryEntries;
70 /// The virtual files that we have allocated.
71 SmallVector<FileEntry *, 4> VirtualFileEntries;
72
73 /// A set of files that bypass the maps and uniquing. They can have
74 /// conflicting filenames.
75 SmallVector<FileEntry *, 0> BypassFileEntries;
76
77 /// A cache that maps paths to directory entries (either real or
78 /// virtual) we have looked up, or an error that occurred when we looked up
79 /// the directory.
80 ///
81 /// The actual Entries for real directories/files are
82 /// owned by UniqueRealDirs/UniqueRealFiles above, while the Entries
83 /// for virtual directories/files are owned by
84 /// VirtualDirectoryEntries/VirtualFileEntries above.
85 ///
86 llvm::StringMap<llvm::ErrorOr<DirectoryEntry &>, llvm::BumpPtrAllocator>
87 SeenDirEntries;
88
89 /// A cache that maps paths to file entries (either real or
90 /// virtual) we have looked up, or an error that occurred when we looked up
91 /// the file.
92 ///
93 /// \see SeenDirEntries
94 llvm::StringMap<llvm::ErrorOr<FileEntryRef::MapValue>, llvm::BumpPtrAllocator>
95 SeenFileEntries;
96
97 /// A mirror of SeenFileEntries to give fake answers for getBypassFile().
98 ///
99 /// Don't bother hooking up a BumpPtrAllocator. This should be rarely used,
100 /// and only on error paths.
101 std::unique_ptr<llvm::StringMap<llvm::ErrorOr<FileEntryRef::MapValue>>>
102 SeenBypassFileEntries;
103
104 /// The file entry for stdin, if it has been accessed through the FileManager.
106
107 /// The canonical names of files and directories .
108 llvm::DenseMap<const void *, llvm::StringRef> CanonicalNames;
109
110 /// Storage for canonical names that we have computed.
111 llvm::BumpPtrAllocator CanonicalNameStorage;
112
113 /// Each FileEntry we create is assigned a unique ID #.
114 ///
115 unsigned NextFileUID;
116
117 /// Statistics gathered during the lifetime of the FileManager.
118 unsigned NumDirLookups = 0;
119 unsigned NumFileLookups = 0;
120 unsigned NumDirCacheMisses = 0;
121 unsigned NumFileCacheMisses = 0;
122
123 // Caching.
124 std::unique_ptr<FileSystemStatCache> StatCache;
125
126 std::error_code getStatValue(StringRef Path, llvm::vfs::Status &Status,
127 bool isFile, std::unique_ptr<llvm::vfs::File> *F,
128 bool IsText = true);
129
130 /// Add all ancestors of the given path (pointing to either a file
131 /// or a directory) as virtual directories.
132 void addAncestorsAsVirtualDirs(StringRef Path);
133
134 /// Fills the RealPathName in file entry.
135 void fillRealPathName(FileEntry *UFE, llvm::StringRef FileName);
136
137public:
138 /// Construct a file manager, optionally with a custom VFS.
139 ///
140 /// \param FS if non-null, the VFS to use. Otherwise uses
141 /// llvm::vfs::getRealFileSystem().
142 FileManager(const FileSystemOptions &FileSystemOpts,
145
146 /// Installs the provided FileSystemStatCache object within
147 /// the FileManager.
148 ///
149 /// Ownership of this object is transferred to the FileManager.
150 ///
151 /// \param statCache the new stat cache to install. Ownership of this
152 /// object is transferred to the FileManager.
153 void setStatCache(std::unique_ptr<FileSystemStatCache> statCache);
154
155 /// Removes the FileSystemStatCache object from the manager.
156 void clearStatCache();
157
158 /// Returns the number of unique real file entries cached by the file manager.
159 size_t getNumUniqueRealFiles() const { return UniqueRealFiles.size(); }
160
161 /// Lookup, cache, and verify the specified directory (real or
162 /// virtual).
163 ///
164 /// This returns a \c std::error_code if there was an error reading the
165 /// directory. On success, returns the reference to the directory entry
166 /// together with the exact path that was used to access a file by a
167 /// particular call to getDirectoryRef.
168 ///
169 /// \param CacheFailure If true and the file does not exist, we'll cache
170 /// the failure to find this file.
172 bool CacheFailure = true);
173
174 /// Get a \c DirectoryEntryRef if it exists, without doing anything on error.
176 bool CacheFailure = true) {
177 return llvm::expectedToOptional(getDirectoryRef(DirName, CacheFailure));
178 }
179
180 /// Lookup, cache, and verify the specified directory (real or
181 /// virtual).
182 ///
183 /// This function is deprecated and will be removed at some point in the
184 /// future, new clients should use
185 /// \c getDirectoryRef.
186 ///
187 /// This returns a \c std::error_code if there was an error reading the
188 /// directory. If there is no error, the DirectoryEntry is guaranteed to be
189 /// non-NULL.
190 ///
191 /// \param CacheFailure If true and the file does not exist, we'll cache
192 /// the failure to find this file.
193 LLVM_DEPRECATED("Functions returning DirectoryEntry are deprecated.",
194 "getOptionalDirectoryRef()")
195 llvm::ErrorOr<const DirectoryEntry *>
196 getDirectory(StringRef DirName, bool CacheFailure = true);
197
198 /// Lookup, cache, and verify the specified file (real or
199 /// virtual).
200 ///
201 /// This function is deprecated and will be removed at some point in the
202 /// future, new clients should use
203 /// \c getFileRef.
204 ///
205 /// This returns a \c std::error_code if there was an error loading the file.
206 /// If there is no error, the FileEntry is guaranteed to be non-NULL.
207 ///
208 /// \param OpenFile if true and the file exists, it will be opened.
209 ///
210 /// \param CacheFailure If true and the file does not exist, we'll cache
211 /// the failure to find this file.
212 LLVM_DEPRECATED("Functions returning FileEntry are deprecated.",
214 llvm::ErrorOr<const FileEntry *>
215 getFile(StringRef Filename, bool OpenFile = false, bool CacheFailure = true);
216
217 /// Lookup, cache, and verify the specified file (real or virtual). Return the
218 /// reference to the file entry together with the exact path that was used to
219 /// access a file by a particular call to getFileRef. If the underlying VFS is
220 /// a redirecting VFS that uses external file names, the returned FileEntryRef
221 /// will use the external name instead of the filename that was passed to this
222 /// method.
223 ///
224 /// This returns a \c std::error_code if there was an error loading the file,
225 /// or a \c FileEntryRef otherwise.
226 ///
227 /// \param OpenFile if true and the file exists, it will be opened.
228 ///
229 /// \param CacheFailure If true and the file does not exist, we'll cache
230 /// the failure to find this file.
232 bool OpenFile = false,
233 bool CacheFailure = true,
234 bool IsText = true);
235
236 /// Get the FileEntryRef for stdin, returning an error if stdin cannot be
237 /// read.
238 ///
239 /// This reads and caches stdin before returning. Subsequent calls return the
240 /// same file entry, and a reference to the cached input is returned by calls
241 /// to getBufferForFile.
243
244 /// Get a FileEntryRef if it exists, without doing anything on error.
246 bool OpenFile = false,
247 bool CacheFailure = true) {
248 return llvm::expectedToOptional(
249 getFileRef(Filename, OpenFile, CacheFailure));
250 }
251
252 /// Returns the current file system options
253 FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
254 const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
255
256 llvm::vfs::FileSystem &getVirtualFileSystem() const { return *FS; }
259 return FS;
260 }
261
262 /// Enable or disable tracking of VFS usage. Used to not track full header
263 /// search and implicit modulemap lookup.
264 void trackVFSUsage(bool Active);
265
267 this->FS = std::move(FS);
268 }
269
270 /// Retrieve a file entry for a "virtual" file that acts as
271 /// if there were a file with the given name on disk.
272 ///
273 /// The file itself is not accessed.
275 time_t ModificationTime);
276
277 LLVM_DEPRECATED("Functions returning FileEntry are deprecated.",
278 "getVirtualFileRef()")
279 const FileEntry *getVirtualFile(StringRef Filename, off_t Size,
281
282 /// Retrieve a FileEntry that bypasses VFE, which is expected to be a virtual
283 /// file entry, to access the real file. The returned FileEntry will have
284 /// the same filename as FE but a different identity and its own stat.
285 ///
286 /// This should be used only for rare error recovery paths because it
287 /// bypasses all mapping and uniquing, blindly creating a new FileEntry.
288 /// There is no attempt to deduplicate these; if you bypass the same file
289 /// twice, you get two new file entries.
291
292 /// Open the specified file as a MemoryBuffer, returning a new
293 /// MemoryBuffer if successful, otherwise returning null.
294 /// The IsText parameter controls whether the file should be opened as a text
295 /// or binary file, and should be set to false if the file contents should be
296 /// treated as binary.
297 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
298 getBufferForFile(FileEntryRef Entry, bool isVolatile = false,
299 bool RequiresNullTerminator = true,
300 std::optional<int64_t> MaybeLimit = std::nullopt,
301 bool IsText = true);
302 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
303 getBufferForFile(StringRef Filename, bool isVolatile = false,
304 bool RequiresNullTerminator = true,
305 std::optional<int64_t> MaybeLimit = std::nullopt,
306 bool IsText = true) const {
307 return getBufferForFileImpl(Filename,
308 /*FileSize=*/MaybeLimit.value_or(-1),
309 isVolatile, RequiresNullTerminator, IsText);
310 }
311
312private:
313 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
314 getBufferForFileImpl(StringRef Filename, int64_t FileSize, bool isVolatile,
315 bool RequiresNullTerminator, bool IsText) const;
316
317 DirectoryEntry *&getRealDirEntry(const llvm::vfs::Status &Status);
318
319public:
320 /// Get the 'stat' information for the given \p Path.
321 ///
322 /// If the path is relative, it will be resolved against the WorkingDir of the
323 /// FileManager's FileSystemOptions.
324 ///
325 /// \returns a \c std::error_code describing an error, if there was one
326 std::error_code getNoncachedStatValue(StringRef Path,
327 llvm::vfs::Status &Result);
328
329 /// If path is not absolute and FileSystemOptions set the working
330 /// directory, the path is modified to be relative to the given
331 /// working directory.
332 /// \returns true if \c path changed.
334
335 /// Makes \c Path absolute taking into account FileSystemOptions and the
336 /// working directory option.
337 /// \returns true if \c Path changed to absolute.
339
340 /// Produce an array mapping from the unique IDs assigned to each
341 /// file to the corresponding FileEntryRef.
342 void
344
345 /// Retrieve the canonical name for a given directory.
346 ///
347 /// This is a very expensive operation, despite its results being cached,
348 /// and should only be used when the physical layout of the file system is
349 /// required, which is (almost) never.
350 StringRef getCanonicalName(DirectoryEntryRef Dir);
351
352 /// Retrieve the canonical name for a given file.
353 ///
354 /// This is a very expensive operation, despite its results being cached,
355 /// and should only be used when the physical layout of the file system is
356 /// required, which is (almost) never.
358
359private:
360 /// Retrieve the canonical name for a given file or directory.
361 ///
362 /// The first param is a key in the CanonicalNames array.
363 StringRef getCanonicalName(const void *Entry, StringRef Name);
364
365public:
366 void PrintStats() const;
367
368 /// Import statistics from a child FileManager and add them to this current
369 /// FileManager.
370 void AddStats(const FileManager &Other);
371};
372
373} // end namespace clang
374
375#endif // LLVM_CLANG_BASIC_FILEMANAGER_H
IndirectLocalPath & Path
Defines interfaces for clang::DirectoryEntry and clang::DirectoryEntryRef.
Defines interfaces for clang::FileEntry and clang::FileEntryRef.
Defines the clang::FileSystemOptions interface.
StringRef Filename
Definition: Format.cpp:3032
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
Cached information about one directory (either on disk or in the virtual file system).
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition: FileEntry.h:57
Cached information about one file (either on disk or in the virtual file system).
Definition: FileEntry.h:305
Implements support for file system lookup, file system caching, and directory search management.
Definition: FileManager.h:53
void AddStats(const FileManager &Other)
Import statistics from a child FileManager and add them to this current FileManager.
void trackVFSUsage(bool Active)
Enable or disable tracking of VFS usage.
void clearStatCache()
Removes the FileSystemStatCache object from the manager.
Definition: FileManager.cpp:63
off_t time_t ModificationTime
Definition: FileManager.h:280
llvm::vfs::FileSystem & getVirtualFileSystem() const
Definition: FileManager.h:256
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(FileEntryRef Entry, bool isVolatile=false, bool RequiresNullTerminator=true, std::optional< int64_t > MaybeLimit=std::nullopt, bool IsText=true)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
std::error_code getNoncachedStatValue(StringRef Path, llvm::vfs::Status &Result)
Get the 'stat' information for the given Path.
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:245
llvm::Expected< FileEntryRef > getSTDIN()
Get the FileEntryRef for stdin, returning an error if stdin cannot be read.
StringRef getCanonicalName(DirectoryEntryRef Dir)
Retrieve the canonical name for a given directory.
void GetUniqueIDMapping(SmallVectorImpl< OptionalFileEntryRef > &UIDToFiles) const
Produce an array mapping from the unique IDs assigned to each file to the corresponding FileEntryRef.
bool makeAbsolutePath(SmallVectorImpl< char > &Path) const
Makes Path absolute taking into account FileSystemOptions and the working directory option.
LLVM_DEPRECATED("Functions returning FileEntry are deprecated.", "getVirtualFileRef()") const FileEntry *getVirtualFile(StringRef Filename
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
void setStatCache(std::unique_ptr< FileSystemStatCache > statCache)
Installs the provided FileSystemStatCache object within the FileManager.
Definition: FileManager.cpp:58
FileSystemOptions & getFileSystemOpts()
Returns the current file system options.
Definition: FileManager.h:253
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
Definition: FileManager.h:258
const FileSystemOptions & getFileSystemOpts() const
Definition: FileManager.h:254
FileEntryRef getVirtualFileRef(StringRef Filename, off_t Size, time_t ModificationTime)
Retrieve a file entry for a "virtual" file that acts as if there were a file with the given name on d...
size_t getNumUniqueRealFiles() const
Returns the number of unique real file entries cached by the file manager.
Definition: FileManager.h:159
bool FixupRelativePath(SmallVectorImpl< char > &path) const
If path is not absolute and FileSystemOptions set the working directory, the path is modified to be r...
void PrintStats() const
OptionalFileEntryRef getBypassFile(FileEntryRef VFE)
Retrieve a FileEntry that bypasses VFE, which is expected to be a virtual file entry,...
void setVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS)
Definition: FileManager.h:266
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:175
LLVM_DEPRECATED("Functions returning DirectoryEntry are deprecated.", "getOptionalDirectoryRef()") llvm LLVM_DEPRECATED("Functions returning FileEntry are deprecated.", "getOptionalFileRef()") llvm llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Lookup, cache, and verify the specified directory (real or virtual).
Keeps track of options that affect how file operations are performed.
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
@ Other
Other implicit parameter.
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
#define true
Definition: stdbool.h:25
#define false
Definition: stdbool.h:26