1 //===--- FileSystemStatCache.h - Caching for 'stat' calls -------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief Defines the FileSystemStatCache interface.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H
16 #define LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H
18 #include "clang/Basic/LLVM.h"
19 #include "llvm/ADT/StringMap.h"
20 #include "llvm/Support/FileSystem.h"
30 // FIXME: should probably replace this with vfs::Status
35 llvm::sys::fs::UniqueID UniqueID;
39 bool IsVFSMapped; // FIXME: remove this when files support multiple names
41 : Size(0), ModTime(0), IsDirectory(false), IsNamedPipe(false),
42 InPCH(false), IsVFSMapped(false) {}
45 /// \brief Abstract interface for introducing a FileManager cache for 'stat'
46 /// system calls, which is used by precompiled and pretokenized headers to
47 /// improve performance.
48 class FileSystemStatCache {
49 virtual void anchor();
51 std::unique_ptr<FileSystemStatCache> NextStatCache;
54 virtual ~FileSystemStatCache() {}
57 CacheExists, ///< We know the file exists and its cached stat data.
58 CacheMissing ///< We know that the file doesn't exist.
61 /// \brief Get the 'stat' information for the specified path, using the cache
62 /// to accelerate it if possible.
64 /// \returns \c true if the path does not exist or \c false if it exists.
66 /// If isFile is true, then this lookup should only return success for files
67 /// (not directories). If it is false this lookup should only return
68 /// success for directories (not files). On a successful file lookup, the
69 /// implementation can optionally fill in \p F with a valid \p File object and
70 /// the client guarantees that it will close it.
71 static bool get(StringRef Path, FileData &Data, bool isFile,
72 std::unique_ptr<vfs::File> *F, FileSystemStatCache *Cache,
75 /// \brief Sets the next stat call cache in the chain of stat caches.
76 /// Takes ownership of the given stat cache.
77 void setNextStatCache(std::unique_ptr<FileSystemStatCache> Cache) {
78 NextStatCache = std::move(Cache);
81 /// \brief Retrieve the next stat call cache in the chain.
82 FileSystemStatCache *getNextStatCache() { return NextStatCache.get(); }
84 /// \brief Retrieve the next stat call cache in the chain, transferring
85 /// ownership of this cache (and, transitively, all of the remaining caches)
87 std::unique_ptr<FileSystemStatCache> takeNextStatCache() {
88 return std::move(NextStatCache);
92 // FIXME: The pointer here is a non-owning/optional reference to the
93 // unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but
94 // Optional needs some work to support references so this isn't possible yet.
95 virtual LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
96 std::unique_ptr<vfs::File> *F,
97 vfs::FileSystem &FS) = 0;
99 LookupResult statChained(StringRef Path, FileData &Data, bool isFile,
100 std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) {
101 if (FileSystemStatCache *Next = getNextStatCache())
102 return Next->getStat(Path, Data, isFile, F, FS);
104 // If we hit the end of the list of stat caches to try, just compute and
105 // return it without a cache.
106 return get(Path, Data, isFile, F, nullptr, FS) ? CacheMissing : CacheExists;
110 /// \brief A stat "cache" that can be used by FileManager to keep
111 /// track of the results of stat() calls that occur throughout the
112 /// execution of the front end.
113 class MemorizeStatCalls : public FileSystemStatCache {
115 /// \brief The set of stat() calls that have been seen.
116 llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls;
118 typedef llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator
121 iterator begin() const { return StatCalls.begin(); }
122 iterator end() const { return StatCalls.end(); }
124 LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
125 std::unique_ptr<vfs::File> *F,
126 vfs::FileSystem &FS) override;
129 } // end namespace clang