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/types.h>
     22 #include <sys/stat.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 FileDescriptor is non-null, then this lookup should only return success
     48   /// for files (not directories).  If it is null 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, int *FileDescriptor,
     53                   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                                int *FileDescriptor) = 0;
     73 
     74   LookupResult statChained(const char *Path, struct stat &StatBuf,
     75                            int *FileDescriptor) {
     76     if (FileSystemStatCache *Next = getNextStatCache())
     77       return Next->getStat(Path, StatBuf, 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, FileDescriptor, 0) ? CacheMissing : CacheExists;
     82   }
     83 };
     84 
     85 /// \brief A stat "cache" that can be used by FileManager to keep
     86 /// track of the results of stat() calls that occur throughout the
     87 /// execution of the front end.
     88 class MemorizeStatCalls : public FileSystemStatCache {
     89 public:
     90   /// \brief The set of stat() calls that have been seen.
     91   llvm::StringMap<struct stat, llvm::BumpPtrAllocator> StatCalls;
     92 
     93   typedef llvm::StringMap<struct stat, llvm::BumpPtrAllocator>::const_iterator
     94   iterator;
     95 
     96   iterator begin() const { return StatCalls.begin(); }
     97   iterator end() const { return StatCalls.end(); }
     98 
     99   virtual LookupResult getStat(const char *Path, struct stat &StatBuf,
    100                                int *FileDescriptor);
    101 };
    102 
    103 } // end namespace clang
    104 
    105 #endif
    106