clang 19.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,
128 std::unique_ptr<llvm::vfs::File> *F);
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::ErrorOr<const DirectoryEntry *>
194 getDirectory(StringRef DirName, bool CacheFailure = true);
195
196 /// Lookup, cache, and verify the specified file (real or
197 /// virtual).
198 ///
199 /// This function is deprecated and will be removed at some point in the
200 /// future, new clients should use
201 /// \c getFileRef.
202 ///
203 /// This returns a \c std::error_code if there was an error loading the file.
204 /// If there is no error, the FileEntry is guaranteed to be non-NULL.
205 ///
206 /// \param OpenFile if true and the file exists, it will be opened.
207 ///
208 /// \param CacheFailure If true and the file does not exist, we'll cache
209 /// the failure to find this file.
210 llvm::ErrorOr<const FileEntry *>
211 getFile(StringRef Filename, bool OpenFile = false, bool CacheFailure = true);
212
213 /// Lookup, cache, and verify the specified file (real or virtual). Return the
214 /// reference to the file entry together with the exact path that was used to
215 /// access a file by a particular call to getFileRef. If the underlying VFS is
216 /// a redirecting VFS that uses external file names, the returned FileEntryRef
217 /// will use the external name instead of the filename that was passed to this
218 /// method.
219 ///
220 /// This returns a \c std::error_code if there was an error loading the file,
221 /// or a \c FileEntryRef otherwise.
222 ///
223 /// \param OpenFile if true and the file exists, it will be opened.
224 ///
225 /// \param CacheFailure If true and the file does not exist, we'll cache
226 /// the failure to find this file.
228 bool OpenFile = false,
229 bool CacheFailure = true);
230
231 /// Get the FileEntryRef for stdin, returning an error if stdin cannot be
232 /// read.
233 ///
234 /// This reads and caches stdin before returning. Subsequent calls return the
235 /// same file entry, and a reference to the cached input is returned by calls
236 /// to getBufferForFile.
238
239 /// Get a FileEntryRef if it exists, without doing anything on error.
241 bool OpenFile = false,
242 bool CacheFailure = true) {
243 return llvm::expectedToOptional(
244 getFileRef(Filename, OpenFile, CacheFailure));
245 }
246
247 /// Returns the current file system options
248 FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
249 const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
250
251 llvm::vfs::FileSystem &getVirtualFileSystem() const { return *FS; }
254 return FS;
255 }
256
257 /// Enable or disable tracking of VFS usage. Used to not track full header
258 /// search and implicit modulemap lookup.
259 void trackVFSUsage(bool Active);
260
262 this->FS = std::move(FS);
263 }
264
265 /// Retrieve a file entry for a "virtual" file that acts as
266 /// if there were a file with the given name on disk.
267 ///
268 /// The file itself is not accessed.
269 FileEntryRef getVirtualFileRef(StringRef Filename, off_t Size,
270 time_t ModificationTime);
271
272 const FileEntry *getVirtualFile(StringRef Filename, off_t Size,
273 time_t ModificationTime);
274
275 /// Retrieve a FileEntry that bypasses VFE, which is expected to be a virtual
276 /// file entry, to access the real file. The returned FileEntry will have
277 /// the same filename as FE but a different identity and its own stat.
278 ///
279 /// This should be used only for rare error recovery paths because it
280 /// bypasses all mapping and uniquing, blindly creating a new FileEntry.
281 /// There is no attempt to deduplicate these; if you bypass the same file
282 /// twice, you get two new file entries.
284
285 /// Open the specified file as a MemoryBuffer, returning a new
286 /// MemoryBuffer if successful, otherwise returning null.
287 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
288 getBufferForFile(FileEntryRef Entry, bool isVolatile = false,
289 bool RequiresNullTerminator = true);
290 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
291 getBufferForFile(StringRef Filename, bool isVolatile = false,
292 bool RequiresNullTerminator = true) const {
293 return getBufferForFileImpl(Filename, /*FileSize=*/-1, isVolatile,
294 RequiresNullTerminator);
295 }
296
297private:
298 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
299 getBufferForFileImpl(StringRef Filename, int64_t FileSize, bool isVolatile,
300 bool RequiresNullTerminator) const;
301
302public:
303 /// Get the 'stat' information for the given \p Path.
304 ///
305 /// If the path is relative, it will be resolved against the WorkingDir of the
306 /// FileManager's FileSystemOptions.
307 ///
308 /// \returns a \c std::error_code describing an error, if there was one
309 std::error_code getNoncachedStatValue(StringRef Path,
310 llvm::vfs::Status &Result);
311
312 /// If path is not absolute and FileSystemOptions set the working
313 /// directory, the path is modified to be relative to the given
314 /// working directory.
315 /// \returns true if \c path changed.
317
318 /// Makes \c Path absolute taking into account FileSystemOptions and the
319 /// working directory option.
320 /// \returns true if \c Path changed to absolute.
321 bool makeAbsolutePath(SmallVectorImpl<char> &Path) const;
322
323 /// Produce an array mapping from the unique IDs assigned to each
324 /// file to the corresponding FileEntryRef.
325 void
327
328 /// Retrieve the canonical name for a given directory.
329 ///
330 /// This is a very expensive operation, despite its results being cached,
331 /// and should only be used when the physical layout of the file system is
332 /// required, which is (almost) never.
333 StringRef getCanonicalName(DirectoryEntryRef Dir);
334
335 /// Retrieve the canonical name for a given file.
336 ///
337 /// This is a very expensive operation, despite its results being cached,
338 /// and should only be used when the physical layout of the file system is
339 /// required, which is (almost) never.
341
342private:
343 /// Retrieve the canonical name for a given file or directory.
344 ///
345 /// The first param is a key in the CanonicalNames array.
346 StringRef getCanonicalName(const void *Entry, StringRef Name);
347
348public:
349 void PrintStats() const;
350
351 /// Import statistics from a child FileManager and add them to this current
352 /// FileManager.
353 void AddStats(const FileManager &Other);
354};
355
356} // end namespace clang
357
358#endif // LLVM_CLANG_BASIC_FILEMANAGER_H
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:2971
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...
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:300
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
llvm::vfs::FileSystem & getVirtualFileSystem() const
Definition: FileManager.h:251
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:240
llvm::ErrorOr< const DirectoryEntry * > getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
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.
const FileEntry * getVirtualFile(StringRef Filename, off_t Size, time_t ModificationTime)
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(FileEntryRef Entry, bool isVolatile=false, bool RequiresNullTerminator=true)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
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:248
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
Definition: FileManager.h:253
const FileSystemOptions & getFileSystemOpts() const
Definition: FileManager.h:249
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...
llvm::ErrorOr< const FileEntry * > getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(StringRef Filename, bool isVolatile=false, bool RequiresNullTerminator=true) const
Definition: FileManager.h:291
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:261
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:175
llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (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