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