1 //===- FileSystemStatCache.h - Caching for 'stat' calls ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 /// \file 11 /// Defines the FileSystemStatCache interface. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H 16 #define LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H 17 18 #include "clang/Basic/LLVM.h" 19 #include "llvm/ADT/StringMap.h" 20 #include "llvm/ADT/StringRef.h" 21 #include "llvm/Support/Allocator.h" 22 #include "llvm/Support/FileSystem.h" 23 #include <cstdint> 24 #include <ctime> 25 #include <memory> 26 #include <string> 27 #include <utility> 28 29 namespace llvm { 30 31 namespace vfs { 32 33 class File; 34 class FileSystem; 35 36 } // namespace vfs 37 } // namespace llvm 38 39 namespace clang { 40 41 // FIXME: should probably replace this with vfs::Status 42 struct FileData { 43 std::string Name; 44 uint64_t Size = 0; 45 time_t ModTime = 0; 46 llvm::sys::fs::UniqueID UniqueID; 47 bool IsDirectory = false; 48 bool IsNamedPipe = false; 49 bool InPCH = false; 50 51 // FIXME: remove this when files support multiple names 52 bool IsVFSMapped = false; 53 54 FileData() = default; 55 }; 56 57 /// Abstract interface for introducing a FileManager cache for 'stat' 58 /// system calls, which is used by precompiled and pretokenized headers to 59 /// improve performance. 60 class FileSystemStatCache { 61 virtual void anchor(); 62 63 public: 64 virtual ~FileSystemStatCache() = default; 65 66 enum LookupResult { 67 /// We know the file exists and its cached stat data. 68 CacheExists, 69 70 /// We know that the file doesn't exist. 71 CacheMissing 72 }; 73 74 /// Get the 'stat' information for the specified path, using the cache 75 /// to accelerate it if possible. 76 /// 77 /// \returns \c true if the path does not exist or \c false if it exists. 78 /// 79 /// If isFile is true, then this lookup should only return success for files 80 /// (not directories). If it is false this lookup should only return 81 /// success for directories (not files). On a successful file lookup, the 82 /// implementation can optionally fill in \p F with a valid \p File object and 83 /// the client guarantees that it will close it. 84 static bool get(StringRef Path, FileData &Data, bool isFile, 85 std::unique_ptr<llvm::vfs::File> *F, 86 FileSystemStatCache *Cache, llvm::vfs::FileSystem &FS); 87 88 protected: 89 // FIXME: The pointer here is a non-owning/optional reference to the 90 // unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but 91 // Optional needs some work to support references so this isn't possible yet. 92 virtual LookupResult getStat(StringRef Path, FileData &Data, bool isFile, 93 std::unique_ptr<llvm::vfs::File> *F, 94 llvm::vfs::FileSystem &FS) = 0; 95 }; 96 97 /// A stat "cache" that can be used by FileManager to keep 98 /// track of the results of stat() calls that occur throughout the 99 /// execution of the front end. 100 class MemorizeStatCalls : public FileSystemStatCache { 101 public: 102 /// The set of stat() calls that have been seen. 103 llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls; 104 105 using iterator = 106 llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator; 107 begin()108 iterator begin() const { return StatCalls.begin(); } end()109 iterator end() const { return StatCalls.end(); } 110 111 LookupResult getStat(StringRef Path, FileData &Data, bool isFile, 112 std::unique_ptr<llvm::vfs::File> *F, 113 llvm::vfs::FileSystem &FS) override; 114 }; 115 116 } // namespace clang 117 118 #endif // LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H 119