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 //  This file defines the FileSystemStatCache interface.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_FILESYSTEMSTATCACHE_H
00015 #define LLVM_CLANG_FILESYSTEMSTATCACHE_H
00016 
00017 #include "clang/Basic/LLVM.h"
00018 #include "llvm/ADT/OwningPtr.h"
00019 #include "llvm/ADT/StringMap.h"
00020 #include <sys/types.h>
00021 #include <sys/stat.h>
00022 
00023 namespace clang {
00024 
00025 /// \brief Abstract interface for introducing a FileManager cache for 'stat'
00026 /// system calls, which is used by precompiled and pretokenized headers to
00027 /// improve performance.
00028 class FileSystemStatCache {
00029   virtual void anchor();
00030 protected:
00031   OwningPtr<FileSystemStatCache> NextStatCache;
00032   
00033 public:
00034   virtual ~FileSystemStatCache() {}
00035   
00036   enum LookupResult {
00037     CacheExists,   //< We know the file exists and its cached stat data.
00038     CacheMissing   //< We know that the file doesn't exist.
00039   };
00040 
00041   /// FileSystemStatCache::get - Get the 'stat' information for the specified
00042   /// path, using the cache to accellerate it if possible.  This returns true if
00043   /// the path does not exist or false if it exists.
00044   ///
00045   /// If FileDescriptor is non-null, then this lookup should only return success
00046   /// for files (not directories).  If it is null this lookup should only return
00047   /// success for directories (not files).  On a successful file lookup, the
00048   /// implementation can optionally fill in FileDescriptor with a valid
00049   /// descriptor and the client guarantees that it will close it.
00050   static bool get(const char *Path, struct stat &StatBuf, int *FileDescriptor,
00051                   FileSystemStatCache *Cache);
00052   
00053   
00054   /// \brief Sets the next stat call cache in the chain of stat caches.
00055   /// Takes ownership of the given stat cache.
00056   void setNextStatCache(FileSystemStatCache *Cache) {
00057     NextStatCache.reset(Cache);
00058   }
00059   
00060   /// \brief Retrieve the next stat call cache in the chain.
00061   FileSystemStatCache *getNextStatCache() { return NextStatCache.get(); }
00062   
00063   /// \brief Retrieve the next stat call cache in the chain, transferring
00064   /// ownership of this cache (and, transitively, all of the remaining caches)
00065   /// to the caller.
00066   FileSystemStatCache *takeNextStatCache() { return NextStatCache.take(); }
00067   
00068 protected:
00069   virtual LookupResult getStat(const char *Path, struct stat &StatBuf,
00070                                int *FileDescriptor) = 0;
00071 
00072   LookupResult statChained(const char *Path, struct stat &StatBuf,
00073                            int *FileDescriptor) {
00074     if (FileSystemStatCache *Next = getNextStatCache())
00075       return Next->getStat(Path, StatBuf, FileDescriptor);
00076     
00077     // If we hit the end of the list of stat caches to try, just compute and
00078     // return it without a cache.
00079     return get(Path, StatBuf, FileDescriptor, 0) ? CacheMissing : CacheExists;
00080   }
00081 };
00082 
00083 /// \brief A stat "cache" that can be used by FileManager to keep
00084 /// track of the results of stat() calls that occur throughout the
00085 /// execution of the front end.
00086 class MemorizeStatCalls : public FileSystemStatCache {
00087 public:
00088   /// \brief The set of stat() calls that have been seen.
00089   llvm::StringMap<struct stat, llvm::BumpPtrAllocator> StatCalls;
00090   
00091   typedef llvm::StringMap<struct stat, llvm::BumpPtrAllocator>::const_iterator
00092   iterator;
00093   
00094   iterator begin() const { return StatCalls.begin(); }
00095   iterator end() const { return StatCalls.end(); }
00096   
00097   virtual LookupResult getStat(const char *Path, struct stat &StatBuf,
00098                                int *FileDescriptor);
00099 };
00100 
00101 } // end namespace clang
00102 
00103 #endif