• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /// \brief Defines the FileSystemStatCache interface.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_FILESYSTEMSTATCACHE_H
16 #define LLVM_CLANG_FILESYSTEMSTATCACHE_H
17 
18 #include "clang/Basic/LLVM.h"
19 #include "llvm/ADT/StringMap.h"
20 #include "llvm/Support/FileSystem.h"
21 #include <memory>
22 
23 namespace clang {
24 
25 namespace vfs {
26 class File;
27 class FileSystem;
28 }
29 
30 // FIXME: should probably replace this with vfs::Status
31 struct FileData {
32   std::string Name;
33   uint64_t Size;
34   time_t ModTime;
35   llvm::sys::fs::UniqueID UniqueID;
36   bool IsDirectory;
37   bool IsNamedPipe;
38   bool InPCH;
39   bool IsVFSMapped; // FIXME: remove this when files support multiple names
FileDataFileData40   FileData()
41       : Size(0), ModTime(0), IsDirectory(false), IsNamedPipe(false),
42         InPCH(false), IsVFSMapped(false) {}
43 };
44 
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();
50 protected:
51   std::unique_ptr<FileSystemStatCache> NextStatCache;
52 
53 public:
~FileSystemStatCache()54   virtual ~FileSystemStatCache() {}
55 
56   enum LookupResult {
57     CacheExists,   ///< We know the file exists and its cached stat data.
58     CacheMissing   ///< We know that the file doesn't exist.
59   };
60 
61   /// \brief Get the 'stat' information for the specified path, using the cache
62   /// to accelerate it if possible.
63   ///
64   /// \returns \c true if the path does not exist or \c false if it exists.
65   ///
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(const char *Path, FileData &Data, bool isFile,
72                   std::unique_ptr<vfs::File> *F, FileSystemStatCache *Cache,
73                   vfs::FileSystem &FS);
74 
75   /// \brief Sets the next stat call cache in the chain of stat caches.
76   /// Takes ownership of the given stat cache.
setNextStatCache(FileSystemStatCache * Cache)77   void setNextStatCache(FileSystemStatCache *Cache) {
78     NextStatCache.reset(Cache);
79   }
80 
81   /// \brief Retrieve the next stat call cache in the chain.
getNextStatCache()82   FileSystemStatCache *getNextStatCache() { return NextStatCache.get(); }
83 
84   /// \brief Retrieve the next stat call cache in the chain, transferring
85   /// ownership of this cache (and, transitively, all of the remaining caches)
86   /// to the caller.
takeNextStatCache()87   FileSystemStatCache *takeNextStatCache() { return NextStatCache.release(); }
88 
89 protected:
90   // FIXME: The pointer here is a non-owning/optional reference to the
91   // unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but
92   // Optional needs some work to support references so this isn't possible yet.
93   virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
94                                std::unique_ptr<vfs::File> *F,
95                                vfs::FileSystem &FS) = 0;
96 
statChained(const char * Path,FileData & Data,bool isFile,std::unique_ptr<vfs::File> * F,vfs::FileSystem & FS)97   LookupResult statChained(const char *Path, FileData &Data, bool isFile,
98                            std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) {
99     if (FileSystemStatCache *Next = getNextStatCache())
100       return Next->getStat(Path, Data, isFile, F, FS);
101 
102     // If we hit the end of the list of stat caches to try, just compute and
103     // return it without a cache.
104     return get(Path, Data, isFile, F, nullptr, FS) ? CacheMissing : CacheExists;
105   }
106 };
107 
108 /// \brief A stat "cache" that can be used by FileManager to keep
109 /// track of the results of stat() calls that occur throughout the
110 /// execution of the front end.
111 class MemorizeStatCalls : public FileSystemStatCache {
112 public:
113   /// \brief The set of stat() calls that have been seen.
114   llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls;
115 
116   typedef llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator
117   iterator;
118 
begin()119   iterator begin() const { return StatCalls.begin(); }
end()120   iterator end() const { return StatCalls.end(); }
121 
122   LookupResult getStat(const char *Path, FileData &Data, bool isFile,
123                        std::unique_ptr<vfs::File> *F,
124                        vfs::FileSystem &FS) override;
125 };
126 
127 } // end namespace clang
128 
129 #endif
130