41026763377aa15a731f7645744c262aab8e454e
[lldb.git] / clang / lib / Basic / FileManager.cpp
1 //===--- FileManager.cpp - File System Probing and Caching ----------------===//
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 //  This file implements the FileManager interface.
10 //
11 //===----------------------------------------------------------------------===//
12 //
13 // TODO: This should index all interesting directories with dirent calls.
14 //  getdirentries ?
15 //  opendir/readdir_r/closedir ?
16 //
17 //===----------------------------------------------------------------------===//
18
19 #include "clang/Basic/FileManager.h"
20 #include "clang/Basic/FileSystemStatCache.h"
21 #include "llvm/ADT/SmallString.h"
22 #include "llvm/Config/llvm-config.h"
23 #include "llvm/ADT/STLExtras.h"
24 #include "llvm/Support/FileSystem.h"
25 #include "llvm/Support/MemoryBuffer.h"
26 #include "llvm/Support/Path.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include <algorithm>
29 #include <cassert>
30 #include <climits>
31 #include <cstdint>
32 #include <cstdlib>
33 #include <string>
34 #include <utility>
35
36 using namespace clang;
37
38 //===----------------------------------------------------------------------===//
39 // Common logic.
40 //===----------------------------------------------------------------------===//
41
42 FileManager::FileManager(const FileSystemOptions &FSO,
43                          IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS)
44     : FS(std::move(FS)), FileSystemOpts(FSO), SeenDirEntries(64),
45       SeenFileEntries(64), NextFileUID(0) {
46   NumDirLookups = NumFileLookups = 0;
47   NumDirCacheMisses = NumFileCacheMisses = 0;
48
49   // If the caller doesn't provide a virtual file system, just grab the real
50   // file system.
51   if (!this->FS)
52     this->FS = llvm::vfs::getRealFileSystem();
53 }
54
55 FileManager::~FileManager() = default;
56
57 void FileManager::setStatCache(std::unique_ptr<FileSystemStatCache> statCache) {
58   assert(statCache && "No stat cache provided?");
59   StatCache = std::move(statCache);
60 }
61
62 void FileManager::clearStatCache() { StatCache.reset(); }
63
64 /// Retrieve the directory that the given file name resides in.
65 /// Filename can point to either a real file or a virtual file.
66 static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr,
67                                                   StringRef Filename,
68                                                   bool CacheFailure) {
69   if (Filename.empty())
70     return nullptr;
71
72   if (llvm::sys::path::is_separator(Filename[Filename.size() - 1]))
73     return nullptr; // If Filename is a directory.
74
75   StringRef DirName = llvm::sys::path::parent_path(Filename);
76   // Use the current directory if file has no path component.
77   if (DirName.empty())
78     DirName = ".";
79
80   return FileMgr.getDirectory(DirName, CacheFailure);
81 }
82
83 /// Add all ancestors of the given path (pointing to either a file or
84 /// a directory) as virtual directories.
85 void FileManager::addAncestorsAsVirtualDirs(StringRef Path) {
86   StringRef DirName = llvm::sys::path::parent_path(Path);
87   if (DirName.empty())
88     DirName = ".";
89
90   auto &NamedDirEnt = *SeenDirEntries.insert({DirName, nullptr}).first;
91
92   // When caching a virtual directory, we always cache its ancestors
93   // at the same time.  Therefore, if DirName is already in the cache,
94   // we don't need to recurse as its ancestors must also already be in
95   // the cache (or it's a known non-virtual directory).
96   if (NamedDirEnt.second)
97     return;
98
99   // Add the virtual directory to the cache.
100   auto UDE = llvm::make_unique<DirectoryEntry>();
101   UDE->Name = NamedDirEnt.first();
102   NamedDirEnt.second = UDE.get();
103   VirtualDirectoryEntries.push_back(std::move(UDE));
104
105   // Recursively add the other ancestors.
106   addAncestorsAsVirtualDirs(DirName);
107 }
108
109 const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
110                                                 bool CacheFailure) {
111   // stat doesn't like trailing separators except for root directory.
112   // At least, on Win32 MSVCRT, stat() cannot strip trailing '/'.
113   // (though it can strip '\\')
114   if (DirName.size() > 1 &&
115       DirName != llvm::sys::path::root_path(DirName) &&
116       llvm::sys::path::is_separator(DirName.back()))
117     DirName = DirName.substr(0, DirName.size()-1);
118 #ifdef _WIN32
119   // Fixing a problem with "clang C:test.c" on Windows.
120   // Stat("C:") does not recognize "C:" as a valid directory
121   std::string DirNameStr;
122   if (DirName.size() > 1 && DirName.back() == ':' &&
123       DirName.equals_lower(llvm::sys::path::root_name(DirName))) {
124     DirNameStr = DirName.str() + '.';
125     DirName = DirNameStr;
126   }
127 #endif
128
129   ++NumDirLookups;
130
131   // See if there was already an entry in the map.  Note that the map
132   // contains both virtual and real directories.
133   auto SeenDirInsertResult = SeenDirEntries.insert({DirName, nullptr});
134   if (!SeenDirInsertResult.second)
135     return SeenDirInsertResult.first->second;
136
137   // We've not seen this before. Fill it in.
138   ++NumDirCacheMisses;
139   auto &NamedDirEnt = *SeenDirInsertResult.first;
140   assert(!NamedDirEnt.second && "should be newly-created");
141
142   // Get the null-terminated directory name as stored as the key of the
143   // SeenDirEntries map.
144   StringRef InterndDirName = NamedDirEnt.first();
145
146   // Check to see if the directory exists.
147   FileData Data;
148   if (getStatValue(InterndDirName, Data, false, nullptr /*directory lookup*/)) {
149     // There's no real directory at the given path.
150     if (!CacheFailure)
151       SeenDirEntries.erase(DirName);
152     return nullptr;
153   }
154
155   // It exists.  See if we have already opened a directory with the
156   // same inode (this occurs on Unix-like systems when one dir is
157   // symlinked to another, for example) or the same path (on
158   // Windows).
159   DirectoryEntry &UDE = UniqueRealDirs[Data.UniqueID];
160
161   NamedDirEnt.second = &UDE;
162   if (UDE.getName().empty()) {
163     // We don't have this directory yet, add it.  We use the string
164     // key from the SeenDirEntries map as the string.
165     UDE.Name  = InterndDirName;
166   }
167
168   return &UDE;
169 }
170
171 const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
172                                       bool CacheFailure) {
173   ++NumFileLookups;
174
175   // See if there is already an entry in the map.
176   auto SeenFileInsertResult = SeenFileEntries.insert({Filename, nullptr});
177   if (!SeenFileInsertResult.second)
178     return SeenFileInsertResult.first->second;
179
180   // We've not seen this before. Fill it in.
181   ++NumFileCacheMisses;
182   auto &NamedFileEnt = *SeenFileInsertResult.first;
183   assert(!NamedFileEnt.second && "should be newly-created");
184
185   // Get the null-terminated file name as stored as the key of the
186   // SeenFileEntries map.
187   StringRef InterndFileName = NamedFileEnt.first();
188
189   // Look up the directory for the file.  When looking up something like
190   // sys/foo.h we'll discover all of the search directories that have a 'sys'
191   // subdirectory.  This will let us avoid having to waste time on known-to-fail
192   // searches when we go to find sys/bar.h, because all the search directories
193   // without a 'sys' subdir will get a cached failure result.
194   const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename,
195                                                        CacheFailure);
196   if (DirInfo == nullptr) { // Directory doesn't exist, file can't exist.
197     if (!CacheFailure)
198       SeenFileEntries.erase(Filename);
199
200     return nullptr;
201   }
202
203   // FIXME: Use the directory info to prune this, before doing the stat syscall.
204   // FIXME: This will reduce the # syscalls.
205
206   // Check to see if the file exists.
207   std::unique_ptr<llvm::vfs::File> F;
208   FileData Data;
209   if (getStatValue(InterndFileName, Data, true, openFile ? &F : nullptr)) {
210     // There's no real file at the given path.
211     if (!CacheFailure)
212       SeenFileEntries.erase(Filename);
213
214     return nullptr;
215   }
216
217   assert((openFile || !F) && "undesired open file");
218
219   // It exists.  See if we have already opened a file with the same inode.
220   // This occurs when one dir is symlinked to another, for example.
221   FileEntry &UFE = UniqueRealFiles[Data.UniqueID];
222
223   NamedFileEnt.second = &UFE;
224
225   // If the name returned by getStatValue is different than Filename, re-intern
226   // the name.
227   if (Data.Name != Filename) {
228     auto &NamedFileEnt = *SeenFileEntries.insert({Data.Name, &UFE}).first;
229     assert(NamedFileEnt.second == &UFE &&
230            "filename from getStatValue() refers to wrong file");
231     InterndFileName = NamedFileEnt.first().data();
232   }
233
234   if (UFE.isValid()) { // Already have an entry with this inode, return it.
235
236     // FIXME: this hack ensures that if we look up a file by a virtual path in
237     // the VFS that the getDir() will have the virtual path, even if we found
238     // the file by a 'real' path first. This is required in order to find a
239     // module's structure when its headers/module map are mapped in the VFS.
240     // We should remove this as soon as we can properly support a file having
241     // multiple names.
242     if (DirInfo != UFE.Dir && Data.IsVFSMapped)
243       UFE.Dir = DirInfo;
244
245     // Always update the name to use the last name by which a file was accessed.
246     // FIXME: Neither this nor always using the first name is correct; we want
247     // to switch towards a design where we return a FileName object that
248     // encapsulates both the name by which the file was accessed and the
249     // corresponding FileEntry.
250     UFE.Name = InterndFileName;
251
252     return &UFE;
253   }
254
255   // Otherwise, we don't have this file yet, add it.
256   UFE.Name    = InterndFileName;
257   UFE.Size = Data.Size;
258   UFE.ModTime = Data.ModTime;
259   UFE.Dir     = DirInfo;
260   UFE.UID     = NextFileUID++;
261   UFE.UniqueID = Data.UniqueID;
262   UFE.IsNamedPipe = Data.IsNamedPipe;
263   UFE.InPCH = Data.InPCH;
264   UFE.File = std::move(F);
265   UFE.IsValid = true;
266
267   if (UFE.File) {
268     if (auto PathName = UFE.File->getName())
269       fillRealPathName(&UFE, *PathName);
270   } else if (!openFile) {
271     // We should still fill the path even if we aren't opening the file.
272     fillRealPathName(&UFE, InterndFileName);
273   }
274   return &UFE;
275 }
276
277 const FileEntry *
278 FileManager::getVirtualFile(StringRef Filename, off_t Size,
279                             time_t ModificationTime) {
280   ++NumFileLookups;
281
282   // See if there is already an entry in the map for an existing file.
283   auto &NamedFileEnt = *SeenFileEntries.insert({Filename, nullptr}).first;
284   if (NamedFileEnt.second)
285     return NamedFileEnt.second;
286
287   // We've not seen this before, or the file is cached as non-existent.
288   ++NumFileCacheMisses;
289   addAncestorsAsVirtualDirs(Filename);
290   FileEntry *UFE = nullptr;
291
292   // Now that all ancestors of Filename are in the cache, the
293   // following call is guaranteed to find the DirectoryEntry from the
294   // cache.
295   const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename,
296                                                        /*CacheFailure=*/true);
297   assert(DirInfo &&
298          "The directory of a virtual file should already be in the cache.");
299
300   // Check to see if the file exists. If so, drop the virtual file
301   FileData Data;
302   const char *InterndFileName = NamedFileEnt.first().data();
303   if (getStatValue(InterndFileName, Data, true, nullptr) == 0) {
304     Data.Size = Size;
305     Data.ModTime = ModificationTime;
306     UFE = &UniqueRealFiles[Data.UniqueID];
307
308     NamedFileEnt.second = UFE;
309
310     // If we had already opened this file, close it now so we don't
311     // leak the descriptor. We're not going to use the file
312     // descriptor anyway, since this is a virtual file.
313     if (UFE->File)
314       UFE->closeFile();
315
316     // If we already have an entry with this inode, return it.
317     if (UFE->isValid())
318       return UFE;
319
320     UFE->UniqueID = Data.UniqueID;
321     UFE->IsNamedPipe = Data.IsNamedPipe;
322     UFE->InPCH = Data.InPCH;
323     fillRealPathName(UFE, Data.Name);
324   } else {
325     VirtualFileEntries.push_back(llvm::make_unique<FileEntry>());
326     UFE = VirtualFileEntries.back().get();
327     NamedFileEnt.second = UFE;
328   }
329
330   UFE->Name    = InterndFileName;
331   UFE->Size    = Size;
332   UFE->ModTime = ModificationTime;
333   UFE->Dir     = DirInfo;
334   UFE->UID     = NextFileUID++;
335   UFE->IsValid = true;
336   UFE->File.reset();
337   return UFE;
338 }
339
340 bool FileManager::FixupRelativePath(SmallVectorImpl<char> &path) const {
341   StringRef pathRef(path.data(), path.size());
342
343   if (FileSystemOpts.WorkingDir.empty()
344       || llvm::sys::path::is_absolute(pathRef))
345     return false;
346
347   SmallString<128> NewPath(FileSystemOpts.WorkingDir);
348   llvm::sys::path::append(NewPath, pathRef);
349   path = NewPath;
350   return true;
351 }
352
353 bool FileManager::makeAbsolutePath(SmallVectorImpl<char> &Path) const {
354   bool Changed = FixupRelativePath(Path);
355
356   if (!llvm::sys::path::is_absolute(StringRef(Path.data(), Path.size()))) {
357     FS->makeAbsolute(Path);
358     Changed = true;
359   }
360
361   return Changed;
362 }
363
364 void FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) {
365   llvm::SmallString<128> AbsPath(FileName);
366   // This is not the same as `VFS::getRealPath()`, which resolves symlinks
367   // but can be very expensive on real file systems.
368   // FIXME: the semantic of RealPathName is unclear, and the name might be
369   // misleading. We need to clean up the interface here.
370   makeAbsolutePath(AbsPath);
371   llvm::sys::path::remove_dots(AbsPath, /*remove_dot_dot=*/true);
372   UFE->RealPathName = AbsPath.str();
373 }
374
375 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
376 FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile,
377                               bool ShouldCloseOpenFile) {
378   uint64_t FileSize = Entry->getSize();
379   // If there's a high enough chance that the file have changed since we
380   // got its size, force a stat before opening it.
381   if (isVolatile)
382     FileSize = -1;
383
384   StringRef Filename = Entry->getName();
385   // If the file is already open, use the open file descriptor.
386   if (Entry->File) {
387     auto Result =
388         Entry->File->getBuffer(Filename, FileSize,
389                                /*RequiresNullTerminator=*/true, isVolatile);
390     // FIXME: we need a set of APIs that can make guarantees about whether a
391     // FileEntry is open or not.
392     if (ShouldCloseOpenFile)
393       Entry->closeFile();
394     return Result;
395   }
396
397   // Otherwise, open the file.
398
399   if (FileSystemOpts.WorkingDir.empty())
400     return FS->getBufferForFile(Filename, FileSize,
401                                 /*RequiresNullTerminator=*/true, isVolatile);
402
403   SmallString<128> FilePath(Entry->getName());
404   FixupRelativePath(FilePath);
405   return FS->getBufferForFile(FilePath, FileSize,
406                               /*RequiresNullTerminator=*/true, isVolatile);
407 }
408
409 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
410 FileManager::getBufferForFile(StringRef Filename, bool isVolatile) {
411   if (FileSystemOpts.WorkingDir.empty())
412     return FS->getBufferForFile(Filename, -1, true, isVolatile);
413
414   SmallString<128> FilePath(Filename);
415   FixupRelativePath(FilePath);
416   return FS->getBufferForFile(FilePath.c_str(), -1, true, isVolatile);
417 }
418
419 /// getStatValue - Get the 'stat' information for the specified path,
420 /// using the cache to accelerate it if possible.  This returns true
421 /// if the path points to a virtual file or does not exist, or returns
422 /// false if it's an existent real file.  If FileDescriptor is NULL,
423 /// do directory look-up instead of file look-up.
424 bool FileManager::getStatValue(StringRef Path, FileData &Data, bool isFile,
425                                std::unique_ptr<llvm::vfs::File> *F) {
426   // FIXME: FileSystemOpts shouldn't be passed in here, all paths should be
427   // absolute!
428   if (FileSystemOpts.WorkingDir.empty())
429     return FileSystemStatCache::get(Path, Data, isFile, F,StatCache.get(), *FS);
430
431   SmallString<128> FilePath(Path);
432   FixupRelativePath(FilePath);
433
434   return FileSystemStatCache::get(FilePath.c_str(), Data, isFile, F,
435                                   StatCache.get(), *FS);
436 }
437
438 bool FileManager::getNoncachedStatValue(StringRef Path,
439                                         llvm::vfs::Status &Result) {
440   SmallString<128> FilePath(Path);
441   FixupRelativePath(FilePath);
442
443   llvm::ErrorOr<llvm::vfs::Status> S = FS->status(FilePath.c_str());
444   if (!S)
445     return true;
446   Result = *S;
447   return false;
448 }
449
450 void FileManager::invalidateCache(const FileEntry *Entry) {
451   assert(Entry && "Cannot invalidate a NULL FileEntry");
452
453   SeenFileEntries.erase(Entry->getName());
454
455   // FileEntry invalidation should not block future optimizations in the file
456   // caches. Possible alternatives are cache truncation (invalidate last N) or
457   // invalidation of the whole cache.
458   //
459   // FIXME: This is broken. We sometimes have the same FileEntry* shared
460   // betweeen multiple SeenFileEntries, so this can leave dangling pointers.
461   UniqueRealFiles.erase(Entry->getUniqueID());
462 }
463
464 void FileManager::GetUniqueIDMapping(
465                    SmallVectorImpl<const FileEntry *> &UIDToFiles) const {
466   UIDToFiles.clear();
467   UIDToFiles.resize(NextFileUID);
468
469   // Map file entries
470   for (llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator>::const_iterator
471          FE = SeenFileEntries.begin(), FEEnd = SeenFileEntries.end();
472        FE != FEEnd; ++FE)
473     if (FE->getValue())
474       UIDToFiles[FE->getValue()->getUID()] = FE->getValue();
475
476   // Map virtual file entries
477   for (const auto &VFE : VirtualFileEntries)
478     UIDToFiles[VFE->getUID()] = VFE.get();
479 }
480
481 void FileManager::modifyFileEntry(FileEntry *File,
482                                   off_t Size, time_t ModificationTime) {
483   File->Size = Size;
484   File->ModTime = ModificationTime;
485 }
486
487 StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) {
488   // FIXME: use llvm::sys::fs::canonical() when it gets implemented
489   llvm::DenseMap<const DirectoryEntry *, llvm::StringRef>::iterator Known
490     = CanonicalDirNames.find(Dir);
491   if (Known != CanonicalDirNames.end())
492     return Known->second;
493
494   StringRef CanonicalName(Dir->getName());
495
496   SmallString<4096> CanonicalNameBuf;
497   if (!FS->getRealPath(Dir->getName(), CanonicalNameBuf))
498     CanonicalName = StringRef(CanonicalNameBuf).copy(CanonicalNameStorage);
499
500   CanonicalDirNames.insert({Dir, CanonicalName});
501   return CanonicalName;
502 }
503
504 void FileManager::PrintStats() const {
505   llvm::errs() << "\n*** File Manager Stats:\n";
506   llvm::errs() << UniqueRealFiles.size() << " real files found, "
507                << UniqueRealDirs.size() << " real dirs found.\n";
508   llvm::errs() << VirtualFileEntries.size() << " virtual files found, "
509                << VirtualDirectoryEntries.size() << " virtual dirs found.\n";
510   llvm::errs() << NumDirLookups << " dir lookups, "
511                << NumDirCacheMisses << " dir cache misses.\n";
512   llvm::errs() << NumFileLookups << " file lookups, "
513                << NumFileCacheMisses << " file cache misses.\n";
514
515   //llvm::errs() << PagesMapped << BytesOfPagesMapped << FSLookups;
516 }