110e286aa8d39fb51a21412850265d9dae74613eeChris Lattner//===--- FileSystemStatCache.h - Caching for 'stat' calls -------*- C++ -*-===//
210e286aa8d39fb51a21412850265d9dae74613eeChris Lattner//
310e286aa8d39fb51a21412850265d9dae74613eeChris Lattner//                     The LLVM Compiler Infrastructure
410e286aa8d39fb51a21412850265d9dae74613eeChris Lattner//
510e286aa8d39fb51a21412850265d9dae74613eeChris Lattner// This file is distributed under the University of Illinois Open Source
610e286aa8d39fb51a21412850265d9dae74613eeChris Lattner// License. See LICENSE.TXT for details.
710e286aa8d39fb51a21412850265d9dae74613eeChris Lattner//
810e286aa8d39fb51a21412850265d9dae74613eeChris Lattner//===----------------------------------------------------------------------===//
92f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett///
102f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// \file
112f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// \brief Defines the FileSystemStatCache interface.
122f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett///
1310e286aa8d39fb51a21412850265d9dae74613eeChris Lattner//===----------------------------------------------------------------------===//
1410e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
1510e286aa8d39fb51a21412850265d9dae74613eeChris Lattner#ifndef LLVM_CLANG_FILESYSTEMSTATCACHE_H
1610e286aa8d39fb51a21412850265d9dae74613eeChris Lattner#define LLVM_CLANG_FILESYSTEMSTATCACHE_H
1710e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
186f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith#include "clang/Basic/LLVM.h"
1910e286aa8d39fb51a21412850265d9dae74613eeChris Lattner#include "llvm/ADT/OwningPtr.h"
2010e286aa8d39fb51a21412850265d9dae74613eeChris Lattner#include "llvm/ADT/StringMap.h"
2110e286aa8d39fb51a21412850265d9dae74613eeChris Lattner#include <sys/types.h>
2210e286aa8d39fb51a21412850265d9dae74613eeChris Lattner#include <sys/stat.h>
2310e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
2410e286aa8d39fb51a21412850265d9dae74613eeChris Lattnernamespace clang {
2510e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
2610e286aa8d39fb51a21412850265d9dae74613eeChris Lattner/// \brief Abstract interface for introducing a FileManager cache for 'stat'
2710e286aa8d39fb51a21412850265d9dae74613eeChris Lattner/// system calls, which is used by precompiled and pretokenized headers to
2810e286aa8d39fb51a21412850265d9dae74613eeChris Lattner/// improve performance.
2910e286aa8d39fb51a21412850265d9dae74613eeChris Lattnerclass FileSystemStatCache {
3099ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
3110e286aa8d39fb51a21412850265d9dae74613eeChris Lattnerprotected:
326f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<FileSystemStatCache> NextStatCache;
3310e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
3410e286aa8d39fb51a21412850265d9dae74613eeChris Lattnerpublic:
3510e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  virtual ~FileSystemStatCache() {}
3610e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
3710e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  enum LookupResult {
3849fdccb4595862828aa5cadc1497d466a8031ddaDmitri Gribenko    CacheExists,   ///< We know the file exists and its cached stat data.
3949fdccb4595862828aa5cadc1497d466a8031ddaDmitri Gribenko    CacheMissing   ///< We know that the file doesn't exist.
4010e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  };
4111aa4b03b054cb9d3c201bba5632241145865e29Chris Lattner
42af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Get the 'stat' information for the specified path, using the cache
43af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// to accelerate it if possible.
44af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
45af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \returns \c true if the path does not exist or \c false if it exists.
46898a061f69e1145bf89a987c08203132b9922a3cChris Lattner  ///
47898a061f69e1145bf89a987c08203132b9922a3cChris Lattner  /// If FileDescriptor is non-null, then this lookup should only return success
48898a061f69e1145bf89a987c08203132b9922a3cChris Lattner  /// for files (not directories).  If it is null this lookup should only return
49898a061f69e1145bf89a987c08203132b9922a3cChris Lattner  /// success for directories (not files).  On a successful file lookup, the
50898a061f69e1145bf89a987c08203132b9922a3cChris Lattner  /// implementation can optionally fill in FileDescriptor with a valid
51898a061f69e1145bf89a987c08203132b9922a3cChris Lattner  /// descriptor and the client guarantees that it will close it.
52898a061f69e1145bf89a987c08203132b9922a3cChris Lattner  static bool get(const char *Path, struct stat &StatBuf, int *FileDescriptor,
53898a061f69e1145bf89a987c08203132b9922a3cChris Lattner                  FileSystemStatCache *Cache);
54898a061f69e1145bf89a987c08203132b9922a3cChris Lattner
5510e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
5610e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  /// \brief Sets the next stat call cache in the chain of stat caches.
5710e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  /// Takes ownership of the given stat cache.
5810e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  void setNextStatCache(FileSystemStatCache *Cache) {
5910e286aa8d39fb51a21412850265d9dae74613eeChris Lattner    NextStatCache.reset(Cache);
6010e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  }
6110e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
6210e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  /// \brief Retrieve the next stat call cache in the chain.
6310e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  FileSystemStatCache *getNextStatCache() { return NextStatCache.get(); }
6410e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
6510e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  /// \brief Retrieve the next stat call cache in the chain, transferring
6610e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  /// ownership of this cache (and, transitively, all of the remaining caches)
6710e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  /// to the caller.
6810e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  FileSystemStatCache *takeNextStatCache() { return NextStatCache.take(); }
6910e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
7010e286aa8d39fb51a21412850265d9dae74613eeChris Lattnerprotected:
71898a061f69e1145bf89a987c08203132b9922a3cChris Lattner  virtual LookupResult getStat(const char *Path, struct stat &StatBuf,
72898a061f69e1145bf89a987c08203132b9922a3cChris Lattner                               int *FileDescriptor) = 0;
7311aa4b03b054cb9d3c201bba5632241145865e29Chris Lattner
74898a061f69e1145bf89a987c08203132b9922a3cChris Lattner  LookupResult statChained(const char *Path, struct stat &StatBuf,
75898a061f69e1145bf89a987c08203132b9922a3cChris Lattner                           int *FileDescriptor) {
7610e286aa8d39fb51a21412850265d9dae74613eeChris Lattner    if (FileSystemStatCache *Next = getNextStatCache())
77898a061f69e1145bf89a987c08203132b9922a3cChris Lattner      return Next->getStat(Path, StatBuf, FileDescriptor);
7810e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
79d6f611198089b78e32d3a15fe8bc986204aee1aaChris Lattner    // If we hit the end of the list of stat caches to try, just compute and
80d6f611198089b78e32d3a15fe8bc986204aee1aaChris Lattner    // return it without a cache.
81898a061f69e1145bf89a987c08203132b9922a3cChris Lattner    return get(Path, StatBuf, FileDescriptor, 0) ? CacheMissing : CacheExists;
8210e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  }
8310e286aa8d39fb51a21412850265d9dae74613eeChris Lattner};
8410e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
8510e286aa8d39fb51a21412850265d9dae74613eeChris Lattner/// \brief A stat "cache" that can be used by FileManager to keep
8610e286aa8d39fb51a21412850265d9dae74613eeChris Lattner/// track of the results of stat() calls that occur throughout the
8710e286aa8d39fb51a21412850265d9dae74613eeChris Lattner/// execution of the front end.
8810e286aa8d39fb51a21412850265d9dae74613eeChris Lattnerclass MemorizeStatCalls : public FileSystemStatCache {
8910e286aa8d39fb51a21412850265d9dae74613eeChris Lattnerpublic:
9074e976ba4b0d407bb798ea26476f618e256fc8c7Chris Lattner  /// \brief The set of stat() calls that have been seen.
9174e976ba4b0d407bb798ea26476f618e256fc8c7Chris Lattner  llvm::StringMap<struct stat, llvm::BumpPtrAllocator> StatCalls;
9210e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
9374e976ba4b0d407bb798ea26476f618e256fc8c7Chris Lattner  typedef llvm::StringMap<struct stat, llvm::BumpPtrAllocator>::const_iterator
9410e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  iterator;
9510e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
9610e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  iterator begin() const { return StatCalls.begin(); }
9710e286aa8d39fb51a21412850265d9dae74613eeChris Lattner  iterator end() const { return StatCalls.end(); }
9810e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
99898a061f69e1145bf89a987c08203132b9922a3cChris Lattner  virtual LookupResult getStat(const char *Path, struct stat &StatBuf,
100898a061f69e1145bf89a987c08203132b9922a3cChris Lattner                               int *FileDescriptor);
10110e286aa8d39fb51a21412850265d9dae74613eeChris Lattner};
10210e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
10310e286aa8d39fb51a21412850265d9dae74613eeChris Lattner} // end namespace clang
10410e286aa8d39fb51a21412850265d9dae74613eeChris Lattner
10510e286aa8d39fb51a21412850265d9dae74613eeChris Lattner#endif
106