Home | History | Annotate | Download | only in Basic
      1 //===- MemoryBufferCache.h - Cache for loaded memory buffers ----*- 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 #ifndef LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
     11 #define LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
     12 
     13 #include "llvm/ADT/IntrusiveRefCntPtr.h"
     14 #include "llvm/ADT/StringMap.h"
     15 #include <memory>
     16 
     17 namespace llvm {
     18 class MemoryBuffer;
     19 } // end namespace llvm
     20 
     21 namespace clang {
     22 
     23 /// Manage memory buffers across multiple users.
     24 ///
     25 /// Ensures that multiple users have a consistent view of each buffer.  This is
     26 /// used by \a CompilerInstance when building PCMs to ensure that each \a
     27 /// ModuleManager sees the same files.
     28 ///
     29 /// \a finalizeCurrentBuffers() should be called before creating a new user.
     30 /// This locks in the current buffers, ensuring that no buffer that has already
     31 /// been accessed can be purged, preventing use-after-frees.
     32 class MemoryBufferCache : public llvm::RefCountedBase<MemoryBufferCache> {
     33   struct BufferEntry {
     34     std::unique_ptr<llvm::MemoryBuffer> Buffer;
     35 
     36     /// Track the timeline of when this was added to the cache.
     37     unsigned Index;
     38   };
     39 
     40   /// Cache of buffers.
     41   llvm::StringMap<BufferEntry> Buffers;
     42 
     43   /// Monotonically increasing index.
     44   unsigned NextIndex = 0;
     45 
     46   /// Bumped to prevent "older" buffers from being removed.
     47   unsigned FirstRemovableIndex = 0;
     48 
     49 public:
     50   /// Store the Buffer under the Filename.
     51   ///
     52   /// \pre There is not already buffer is not already in the cache.
     53   /// \return a reference to the buffer as a convenience.
     54   llvm::MemoryBuffer &addBuffer(llvm::StringRef Filename,
     55                                 std::unique_ptr<llvm::MemoryBuffer> Buffer);
     56 
     57   /// Try to remove a buffer from the cache.
     58   ///
     59   /// \return false on success, iff \c !isBufferFinal().
     60   bool tryToRemoveBuffer(llvm::StringRef Filename);
     61 
     62   /// Get a pointer to the buffer if it exists; else nullptr.
     63   llvm::MemoryBuffer *lookupBuffer(llvm::StringRef Filename);
     64 
     65   /// Check whether the buffer is final.
     66   ///
     67   /// \return true iff \a finalizeCurrentBuffers() has been called since the
     68   /// buffer was added.  This prevents buffers from being removed.
     69   bool isBufferFinal(llvm::StringRef Filename);
     70 
     71   /// Finalize the current buffers in the cache.
     72   ///
     73   /// Should be called when creating a new user to ensure previous uses aren't
     74   /// invalidated.
     75   void finalizeCurrentBuffers();
     76 };
     77 
     78 } // end namespace clang
     79 
     80 #endif // LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
     81