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