clang API Documentation

FileSystemStatCache.h
Go to the documentation of this file.
00001 //===--- FileSystemStatCache.h - Caching for 'stat' calls -------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 ///
00010 /// \file
00011 /// \brief Defines the FileSystemStatCache interface.
00012 ///
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H
00016 #define LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H
00017 
00018 #include "clang/Basic/LLVM.h"
00019 #include "llvm/ADT/StringMap.h"
00020 #include "llvm/Support/FileSystem.h"
00021 #include <memory>
00022 
00023 namespace clang {
00024 
00025 namespace vfs {
00026 class File;
00027 class FileSystem;
00028 }
00029 
00030 // FIXME: should probably replace this with vfs::Status
00031 struct FileData {
00032   std::string Name;
00033   uint64_t Size;
00034   time_t ModTime;
00035   llvm::sys::fs::UniqueID UniqueID;
00036   bool IsDirectory;
00037   bool IsNamedPipe;
00038   bool InPCH;
00039   bool IsVFSMapped; // FIXME: remove this when files support multiple names
00040   FileData()
00041       : Size(0), ModTime(0), IsDirectory(false), IsNamedPipe(false),
00042         InPCH(false), IsVFSMapped(false) {}
00043 };
00044 
00045 /// \brief Abstract interface for introducing a FileManager cache for 'stat'
00046 /// system calls, which is used by precompiled and pretokenized headers to
00047 /// improve performance.
00048 class FileSystemStatCache {
00049   virtual void anchor();
00050 protected:
00051   std::unique_ptr<FileSystemStatCache> NextStatCache;
00052 
00053 public:
00054   virtual ~FileSystemStatCache() {}
00055   
00056   enum LookupResult {
00057     CacheExists,   ///< We know the file exists and its cached stat data.
00058     CacheMissing   ///< We know that the file doesn't exist.
00059   };
00060 
00061   /// \brief Get the 'stat' information for the specified path, using the cache
00062   /// to accelerate it if possible.
00063   ///
00064   /// \returns \c true if the path does not exist or \c false if it exists.
00065   ///
00066   /// If isFile is true, then this lookup should only return success for files
00067   /// (not directories).  If it is false this lookup should only return
00068   /// success for directories (not files).  On a successful file lookup, the
00069   /// implementation can optionally fill in \p F with a valid \p File object and
00070   /// the client guarantees that it will close it.
00071   static bool get(const char *Path, FileData &Data, bool isFile,
00072                   std::unique_ptr<vfs::File> *F, FileSystemStatCache *Cache,
00073                   vfs::FileSystem &FS);
00074 
00075   /// \brief Sets the next stat call cache in the chain of stat caches.
00076   /// Takes ownership of the given stat cache.
00077   void setNextStatCache(std::unique_ptr<FileSystemStatCache> Cache) {
00078     NextStatCache = std::move(Cache);
00079   }
00080   
00081   /// \brief Retrieve the next stat call cache in the chain.
00082   FileSystemStatCache *getNextStatCache() { return NextStatCache.get(); }
00083   
00084   /// \brief Retrieve the next stat call cache in the chain, transferring
00085   /// ownership of this cache (and, transitively, all of the remaining caches)
00086   /// to the caller.
00087   std::unique_ptr<FileSystemStatCache> takeNextStatCache() {
00088     return std::move(NextStatCache);
00089   }
00090 
00091 protected:
00092   // FIXME: The pointer here is a non-owning/optional reference to the
00093   // unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but
00094   // Optional needs some work to support references so this isn't possible yet.
00095   virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
00096                                std::unique_ptr<vfs::File> *F,
00097                                vfs::FileSystem &FS) = 0;
00098 
00099   LookupResult statChained(const char *Path, FileData &Data, bool isFile,
00100                            std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) {
00101     if (FileSystemStatCache *Next = getNextStatCache())
00102       return Next->getStat(Path, Data, isFile, F, FS);
00103 
00104     // If we hit the end of the list of stat caches to try, just compute and
00105     // return it without a cache.
00106     return get(Path, Data, isFile, F, nullptr, FS) ? CacheMissing : CacheExists;
00107   }
00108 };
00109 
00110 /// \brief A stat "cache" that can be used by FileManager to keep
00111 /// track of the results of stat() calls that occur throughout the
00112 /// execution of the front end.
00113 class MemorizeStatCalls : public FileSystemStatCache {
00114 public:
00115   /// \brief The set of stat() calls that have been seen.
00116   llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls;
00117 
00118   typedef llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator
00119   iterator;
00120 
00121   iterator begin() const { return StatCalls.begin(); }
00122   iterator end() const { return StatCalls.end(); }
00123 
00124   LookupResult getStat(const char *Path, FileData &Data, bool isFile,
00125                        std::unique_ptr<vfs::File> *F,
00126                        vfs::FileSystem &FS) override;
00127 };
00128 
00129 } // end namespace clang
00130 
00131 #endif