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 // Caching.
118 std::unique_ptr<FileSystemStatCache> StatCache;
119
120 std::error_code getStatValue(StringRef Path, llvm::vfs::Status &Status,
121 bool isFile,
122 std::unique_ptr<llvm::vfs::File> *F);
123
124 /// Add all ancestors of the given path (pointing to either a file
125 /// or a directory) as virtual directories.
126 void addAncestorsAsVirtualDirs(StringRef Path);
127
128 /// Fills the RealPathName in file entry.
129 void fillRealPathName(FileEntry *UFE, llvm::StringRef FileName);
130
131public:
132 /// Construct a file manager, optionally with a custom VFS.
133 ///
134 /// \param FS if non-null, the VFS to use. Otherwise uses
135 /// llvm::vfs::getRealFileSystem().
136 FileManager(const FileSystemOptions &FileSystemOpts,
139
140 /// Installs the provided FileSystemStatCache object within
141 /// the FileManager.
142 ///
143 /// Ownership of this object is transferred to the FileManager.
144 ///
145 /// \param statCache the new stat cache to install. Ownership of this
146 /// object is transferred to the FileManager.
147 void setStatCache(std::unique_ptr<FileSystemStatCache> statCache);
148
149 /// Removes the FileSystemStatCache object from the manager.
150 void clearStatCache();
151
152 /// Returns the number of unique real file entries cached by the file manager.
153 size_t getNumUniqueRealFiles() const { return UniqueRealFiles.size(); }
154
155 /// Lookup, cache, and verify the specified directory (real or
156 /// virtual).
157 ///
158 /// This returns a \c std::error_code if there was an error reading the
159 /// directory. On success, returns the reference to the directory entry
160 /// together with the exact path that was used to access a file by a
161 /// particular call to getDirectoryRef.
162 ///
163 /// \param CacheFailure If true and the file does not exist, we'll cache
164 /// the failure to find this file.
166 bool CacheFailure = true);
167
168 /// Get a \c DirectoryEntryRef if it exists, without doing anything on error.
170 bool CacheFailure = true) {
171 return llvm::expectedToOptional(getDirectoryRef(DirName, CacheFailure));
172 }
173
174 /// Lookup, cache, and verify the specified directory (real or
175 /// virtual).
176 ///
177 /// This function is deprecated and will be removed at some point in the
178 /// future, new clients should use
179 /// \c getDirectoryRef.
180 ///
181 /// This returns a \c std::error_code if there was an error reading the
182 /// directory. If there is no error, the DirectoryEntry is guaranteed to be
183 /// non-NULL.
184 ///
185 /// \param CacheFailure If true and the file does not exist, we'll cache
186 /// the failure to find this file.
187 llvm::ErrorOr<const DirectoryEntry *>
188 getDirectory(StringRef DirName, bool CacheFailure = true);
189
190 /// Lookup, cache, and verify the specified file (real or
191 /// virtual).
192 ///
193 /// This function is deprecated and will be removed at some point in the
194 /// future, new clients should use
195 /// \c getFileRef.
196 ///
197 /// This returns a \c std::error_code if there was an error loading the file.
198 /// If there is no error, the FileEntry is guaranteed to be non-NULL.
199 ///
200 /// \param OpenFile if true and the file exists, it will be opened.
201 ///
202 /// \param CacheFailure If true and the file does not exist, we'll cache
203 /// the failure to find this file.
204 llvm::ErrorOr<const FileEntry *>
205 getFile(StringRef Filename, bool OpenFile = false, bool CacheFailure = true);
206
207 /// Lookup, cache, and verify the specified file (real or virtual). Return the
208 /// reference to the file entry together with the exact path that was used to
209 /// access a file by a particular call to getFileRef. If the underlying VFS is
210 /// a redirecting VFS that uses external file names, the returned FileEntryRef
211 /// will use the external name instead of the filename that was passed to this
212 /// method.
213 ///
214 /// This returns a \c std::error_code if there was an error loading the file,
215 /// or a \c FileEntryRef otherwise.
216 ///
217 /// \param OpenFile if true and the file exists, it will be opened.
218 ///
219 /// \param CacheFailure If true and the file does not exist, we'll cache
220 /// the failure to find this file.
222 bool OpenFile = false,
223 bool CacheFailure = true);
224
225 /// Get the FileEntryRef for stdin, returning an error if stdin cannot be
226 /// read.
227 ///
228 /// This reads and caches stdin before returning. Subsequent calls return the
229 /// same file entry, and a reference to the cached input is returned by calls
230 /// to getBufferForFile.
232
233 /// Get a FileEntryRef if it exists, without doing anything on error.
235 bool OpenFile = false,
236 bool CacheFailure = true) {
237 return llvm::expectedToOptional(
238 getFileRef(Filename, OpenFile, CacheFailure));
239 }
240
241 /// Returns the current file system options
242 FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
243 const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
244
245 llvm::vfs::FileSystem &getVirtualFileSystem() const { return *FS; }
248 return FS;
249 }
250
251 /// Enable or disable tracking of VFS usage. Used to not track full header
252 /// search and implicit modulemap lookup.
253 void trackVFSUsage(bool Active);
254
256 this->FS = std::move(FS);
257 }
258
259 /// Retrieve a file entry for a "virtual" file that acts as
260 /// if there were a file with the given name on disk.
261 ///
262 /// The file itself is not accessed.
263 FileEntryRef getVirtualFileRef(StringRef Filename, off_t Size,
264 time_t ModificationTime);
265
266 const FileEntry *getVirtualFile(StringRef Filename, off_t Size,
267 time_t ModificationTime);
268
269 /// Retrieve a FileEntry that bypasses VFE, which is expected to be a virtual
270 /// file entry, to access the real file. The returned FileEntry will have
271 /// the same filename as FE but a different identity and its own stat.
272 ///
273 /// This should be used only for rare error recovery paths because it
274 /// bypasses all mapping and uniquing, blindly creating a new FileEntry.
275 /// There is no attempt to deduplicate these; if you bypass the same file
276 /// twice, you get two new file entries.
278
279 /// Open the specified file as a MemoryBuffer, returning a new
280 /// MemoryBuffer if successful, otherwise returning null.
281 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
282 getBufferForFile(FileEntryRef Entry, bool isVolatile = false,
283 bool RequiresNullTerminator = true);
284 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
285 getBufferForFile(StringRef Filename, bool isVolatile = false,
286 bool RequiresNullTerminator = true) const {
287 return getBufferForFileImpl(Filename, /*FileSize=*/-1, isVolatile,
288 RequiresNullTerminator);
289 }
290
291private:
292 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
293 getBufferForFileImpl(StringRef Filename, int64_t FileSize, bool isVolatile,
294 bool RequiresNullTerminator) const;
295
296public:
297 /// Get the 'stat' information for the given \p Path.
298 ///
299 /// If the path is relative, it will be resolved against the WorkingDir of the
300 /// FileManager's FileSystemOptions.
301 ///
302 /// \returns a \c std::error_code describing an error, if there was one
303 std::error_code getNoncachedStatValue(StringRef Path,
304 llvm::vfs::Status &Result);
305
306 /// If path is not absolute and FileSystemOptions set the working
307 /// directory, the path is modified to be relative to the given
308 /// working directory.
309 /// \returns true if \c path changed.
311
312 /// Makes \c Path absolute taking into account FileSystemOptions and the
313 /// working directory option.
314 /// \returns true if \c Path changed to absolute.
315 bool makeAbsolutePath(SmallVectorImpl<char> &Path) const;
316
317 /// Produce an array mapping from the unique IDs assigned to each
318 /// file to the corresponding FileEntryRef.
319 void
321
322 /// Retrieve the canonical name for a given directory.
323 ///
324 /// This is a very expensive operation, despite its results being cached,
325 /// and should only be used when the physical layout of the file system is
326 /// required, which is (almost) never.
327 StringRef getCanonicalName(DirectoryEntryRef Dir);
328
329 /// Retrieve the canonical name for a given file.
330 ///
331 /// This is a very expensive operation, despite its results being cached,
332 /// and should only be used when the physical layout of the file system is
333 /// required, which is (almost) never.
335
336private:
337 /// Retrieve the canonical name for a given file or directory.
338 ///
339 /// The first param is a key in the CanonicalNames array.
340 StringRef getCanonicalName(const void *Entry, StringRef Name);
341
342public:
343 void PrintStats() const;
344};
345
346} // end namespace clang
347
348#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:2952
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 trackVFSUsage(bool Active)
Enable or disable tracking of VFS usage.
void clearStatCache()
Removes the FileSystemStatCache object from the manager.
Definition: FileManager.cpp:69
llvm::vfs::FileSystem & getVirtualFileSystem() const
Definition: FileManager.h:245
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:234
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:64
FileSystemOptions & getFileSystemOpts()
Returns the current file system options.
Definition: FileManager.h:242
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
Definition: FileManager.h:247
const FileSystemOptions & getFileSystemOpts() const
Definition: FileManager.h:243
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:285
size_t getNumUniqueRealFiles() const
Returns the number of unique real file entries cached by the file manager.
Definition: FileManager.h:153
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:255
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:169
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.
YAML serialization mapping.
Definition: Dominators.h:30