Home | History | Annotate | Download | only in Basic
      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/OwningPtr.h"
     20 #include "llvm/ADT/StringMap.h"
     21 #include "llvm/Support/FileSystem.h"
     22 #include <sys/stat.h>
     23 #include <sys/types.h>
     24 
     25 namespace clang {
     26 
     27 struct FileData {
     28   uint64_t Size;
     29   time_t ModTime;
     30   llvm::sys::fs::UniqueID UniqueID;
     31   bool IsDirectory;
     32   bool IsNamedPipe;
     33   bool InPCH;
     34 };
     35 
     36 /// \brief Abstract interface for introducing a FileManager cache for 'stat'
     37 /// system calls, which is used by precompiled and pretokenized headers to
     38 /// improve performance.
     39 class FileSystemStatCache {
     40   virtual void anchor();
     41 protected:
     42   OwningPtr<FileSystemStatCache> NextStatCache;
     43 
     44 public:
     45   virtual ~FileSystemStatCache() {}
     46 
     47   enum LookupResult {
     48     CacheExists,   ///< We know the file exists and its cached stat data.
     49     CacheMissing   ///< We know that the file doesn't exist.
     50   };
     51 
     52   /// \brief Get the 'stat' information for the specified path, using the cache
     53   /// to accelerate it if possible.
     54   ///
     55   /// \returns \c true if the path does not exist or \c false if it exists.
     56   ///
     57   /// If isFile is true, then this lookup should only return success for files
     58   /// (not directories).  If it is false this lookup should only return
     59   /// success for directories (not files).  On a successful file lookup, the
     60   /// implementation can optionally fill in FileDescriptor with a valid
     61   /// descriptor and the client guarantees that it will close it.
     62   static bool get(const char *Path, FileData &Data, bool isFile,
     63                   int *FileDescriptor, FileSystemStatCache *Cache);
     64 
     65   /// \brief Sets the next stat call cache in the chain of stat caches.
     66   /// Takes ownership of the given stat cache.
     67   void setNextStatCache(FileSystemStatCache *Cache) {
     68     NextStatCache.reset(Cache);
     69   }
     70 
     71   /// \brief Retrieve the next stat call cache in the chain.
     72   FileSystemStatCache *getNextStatCache() { return NextStatCache.get(); }
     73 
     74   /// \brief Retrieve the next stat call cache in the chain, transferring
     75   /// ownership of this cache (and, transitively, all of the remaining caches)
     76   /// to the caller.
     77   FileSystemStatCache *takeNextStatCache() { return NextStatCache.take(); }
     78 
     79 protected:
     80   virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
     81                                int *FileDescriptor) = 0;
     82 
     83   LookupResult statChained(const char *Path, FileData &Data, bool isFile,
     84                            int *FileDescriptor) {
     85     if (FileSystemStatCache *Next = getNextStatCache())
     86       return Next->getStat(Path, Data, isFile, FileDescriptor);
     87 
     88     // If we hit the end of the list of stat caches to try, just compute and
     89     // return it without a cache.
     90     return get(Path, Data, isFile, FileDescriptor, 0) ? CacheMissing
     91                                                       : CacheExists;
     92   }
     93 };
     94 
     95 /// \brief A stat "cache" that can be used by FileManager to keep
     96 /// track of the results of stat() calls that occur throughout the
     97 /// execution of the front end.
     98 class MemorizeStatCalls : public FileSystemStatCache {
     99 public:
    100   /// \brief The set of stat() calls that have been seen.
    101   llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls;
    102 
    103   typedef llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator
    104   iterator;
    105 
    106   iterator begin() const { return StatCalls.begin(); }
    107   iterator end() const { return StatCalls.end(); }
    108 
    109   virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
    110                                int *FileDescriptor);
    111 };
    112 
    113 } // end namespace clang
    114 
    115 #endif
    116