1 //===--- MemoryBuffer.h - Memory Buffer Interface ---------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the MemoryBuffer interface. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_SUPPORT_MEMORYBUFFER_H 14 #define LLVM_SUPPORT_MEMORYBUFFER_H 15 16 #include "llvm-c/Types.h" 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/Support/Alignment.h" 21 #include "llvm/Support/CBindingWrapping.h" 22 #include "llvm/Support/ErrorOr.h" 23 #include "llvm/Support/MemoryBufferRef.h" 24 #include <cstddef> 25 #include <cstdint> 26 #include <memory> 27 28 namespace llvm { 29 namespace sys { 30 namespace fs { 31 // Duplicated from FileSystem.h to avoid a dependency. 32 #if defined(_WIN32) 33 // A Win32 HANDLE is a typedef of void* 34 using file_t = void *; 35 #else 36 using file_t = int; 37 #endif 38 } // namespace fs 39 } // namespace sys 40 41 /// This interface provides simple read-only access to a block of memory, and 42 /// provides simple methods for reading files and standard input into a memory 43 /// buffer. In addition to basic access to the characters in the file, this 44 /// interface guarantees you can read one character past the end of the file, 45 /// and that this character will read as '\0'. 46 /// 47 /// The '\0' guarantee is needed to support an optimization -- it's intended to 48 /// be more efficient for clients which are reading all the data to stop 49 /// reading when they encounter a '\0' than to continually check the file 50 /// position to see if it has reached the end of the file. 51 class MemoryBuffer { 52 const char *BufferStart; // Start of the buffer. 53 const char *BufferEnd; // End of the buffer. 54 55 protected: 56 MemoryBuffer() = default; 57 58 void init(const char *BufStart, const char *BufEnd, 59 bool RequiresNullTerminator); 60 61 public: 62 MemoryBuffer(const MemoryBuffer &) = delete; 63 MemoryBuffer &operator=(const MemoryBuffer &) = delete; 64 virtual ~MemoryBuffer(); 65 getBufferStart()66 const char *getBufferStart() const { return BufferStart; } getBufferEnd()67 const char *getBufferEnd() const { return BufferEnd; } getBufferSize()68 size_t getBufferSize() const { return BufferEnd-BufferStart; } 69 getBuffer()70 StringRef getBuffer() const { 71 return StringRef(BufferStart, getBufferSize()); 72 } 73 74 /// Return an identifier for this buffer, typically the filename it was read 75 /// from. getBufferIdentifier()76 virtual StringRef getBufferIdentifier() const { return "Unknown buffer"; } 77 78 /// For read-only MemoryBuffer_MMap, mark the buffer as unused in the near 79 /// future and the kernel can free resources associated with it. Further 80 /// access is supported but may be expensive. This calls 81 /// madvise(MADV_DONTNEED) on read-only file mappings on *NIX systems. This 82 /// function should not be called on a writable buffer. dontNeedIfMmap()83 virtual void dontNeedIfMmap() {} 84 85 /// Open the specified file as a MemoryBuffer, returning a new MemoryBuffer 86 /// if successful, otherwise returning null. 87 /// 88 /// \param IsText Set to true to indicate that the file should be read in 89 /// text mode. 90 /// 91 /// \param IsVolatile Set to true to indicate that the contents of the file 92 /// can change outside the user's control, e.g. when libclang tries to parse 93 /// while the user is editing/updating the file or if the file is on an NFS. 94 /// 95 /// \param Alignment Set to indicate that the buffer should be aligned to at 96 /// least the specified alignment. 97 static ErrorOr<std::unique_ptr<MemoryBuffer>> 98 getFile(const Twine &Filename, bool IsText = false, 99 bool RequiresNullTerminator = true, bool IsVolatile = false, 100 std::optional<Align> Alignment = std::nullopt); 101 102 /// Read all of the specified file into a MemoryBuffer as a stream 103 /// (i.e. until EOF reached). This is useful for special files that 104 /// look like a regular file but have 0 size (e.g. /proc/cpuinfo on Linux). 105 static ErrorOr<std::unique_ptr<MemoryBuffer>> 106 getFileAsStream(const Twine &Filename); 107 108 /// Given an already-open file descriptor, map some slice of it into a 109 /// MemoryBuffer. The slice is specified by an \p Offset and \p MapSize. 110 /// Since this is in the middle of a file, the buffer is not null terminated. 111 static ErrorOr<std::unique_ptr<MemoryBuffer>> 112 getOpenFileSlice(sys::fs::file_t FD, const Twine &Filename, uint64_t MapSize, 113 int64_t Offset, bool IsVolatile = false, 114 std::optional<Align> Alignment = std::nullopt); 115 116 /// Given an already-open file descriptor, read the file and return a 117 /// MemoryBuffer. 118 /// 119 /// \param IsVolatile Set to true to indicate that the contents of the file 120 /// can change outside the user's control, e.g. when libclang tries to parse 121 /// while the user is editing/updating the file or if the file is on an NFS. 122 /// 123 /// \param Alignment Set to indicate that the buffer should be aligned to at 124 /// least the specified alignment. 125 static ErrorOr<std::unique_ptr<MemoryBuffer>> 126 getOpenFile(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, 127 bool RequiresNullTerminator = true, bool IsVolatile = false, 128 std::optional<Align> Alignment = std::nullopt); 129 130 /// Open the specified memory range as a MemoryBuffer. Note that InputData 131 /// must be null terminated if RequiresNullTerminator is true. 132 static std::unique_ptr<MemoryBuffer> 133 getMemBuffer(StringRef InputData, StringRef BufferName = "", 134 bool RequiresNullTerminator = true); 135 136 static std::unique_ptr<MemoryBuffer> 137 getMemBuffer(MemoryBufferRef Ref, bool RequiresNullTerminator = true); 138 139 /// Open the specified memory range as a MemoryBuffer, copying the contents 140 /// and taking ownership of it. InputData does not have to be null terminated. 141 static std::unique_ptr<MemoryBuffer> 142 getMemBufferCopy(StringRef InputData, const Twine &BufferName = ""); 143 144 /// Read all of stdin into a file buffer, and return it. 145 static ErrorOr<std::unique_ptr<MemoryBuffer>> getSTDIN(); 146 147 /// Open the specified file as a MemoryBuffer, or open stdin if the Filename 148 /// is "-". 149 static ErrorOr<std::unique_ptr<MemoryBuffer>> 150 getFileOrSTDIN(const Twine &Filename, bool IsText = false, 151 bool RequiresNullTerminator = true, 152 std::optional<Align> Alignment = std::nullopt); 153 154 /// Map a subrange of the specified file as a MemoryBuffer. 155 static ErrorOr<std::unique_ptr<MemoryBuffer>> 156 getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset, 157 bool IsVolatile = false, 158 std::optional<Align> Alignment = std::nullopt); 159 160 //===--------------------------------------------------------------------===// 161 // Provided for performance analysis. 162 //===--------------------------------------------------------------------===// 163 164 /// The kind of memory backing used to support the MemoryBuffer. 165 enum BufferKind { 166 MemoryBuffer_Malloc, 167 MemoryBuffer_MMap 168 }; 169 170 /// Return information on the memory mechanism used to support the 171 /// MemoryBuffer. 172 virtual BufferKind getBufferKind() const = 0; 173 174 MemoryBufferRef getMemBufferRef() const; 175 }; 176 177 /// This class is an extension of MemoryBuffer, which allows copy-on-write 178 /// access to the underlying contents. It only supports creation methods that 179 /// are guaranteed to produce a writable buffer. For example, mapping a file 180 /// read-only is not supported. 181 class WritableMemoryBuffer : public MemoryBuffer { 182 protected: 183 WritableMemoryBuffer() = default; 184 185 public: 186 using MemoryBuffer::getBuffer; 187 using MemoryBuffer::getBufferEnd; 188 using MemoryBuffer::getBufferStart; 189 190 // const_cast is well-defined here, because the underlying buffer is 191 // guaranteed to have been initialized with a mutable buffer. getBufferStart()192 char *getBufferStart() { 193 return const_cast<char *>(MemoryBuffer::getBufferStart()); 194 } getBufferEnd()195 char *getBufferEnd() { 196 return const_cast<char *>(MemoryBuffer::getBufferEnd()); 197 } getBuffer()198 MutableArrayRef<char> getBuffer() { 199 return {getBufferStart(), getBufferEnd()}; 200 } 201 202 static ErrorOr<std::unique_ptr<WritableMemoryBuffer>> 203 getFile(const Twine &Filename, bool IsVolatile = false, 204 std::optional<Align> Alignment = std::nullopt); 205 206 /// Map a subrange of the specified file as a WritableMemoryBuffer. 207 static ErrorOr<std::unique_ptr<WritableMemoryBuffer>> 208 getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset, 209 bool IsVolatile = false, 210 std::optional<Align> Alignment = std::nullopt); 211 212 /// Allocate a new MemoryBuffer of the specified size that is not initialized. 213 /// Note that the caller should initialize the memory allocated by this 214 /// method. The memory is owned by the MemoryBuffer object. 215 /// 216 /// \param Alignment Set to indicate that the buffer should be aligned to at 217 /// least the specified alignment. 218 static std::unique_ptr<WritableMemoryBuffer> 219 getNewUninitMemBuffer(size_t Size, const Twine &BufferName = "", 220 std::optional<Align> Alignment = std::nullopt); 221 222 /// Allocate a new zero-initialized MemoryBuffer of the specified size. Note 223 /// that the caller need not initialize the memory allocated by this method. 224 /// The memory is owned by the MemoryBuffer object. 225 static std::unique_ptr<WritableMemoryBuffer> 226 getNewMemBuffer(size_t Size, const Twine &BufferName = ""); 227 228 private: 229 // Hide these base class factory function so one can't write 230 // WritableMemoryBuffer::getXXX() 231 // and be surprised that he got a read-only Buffer. 232 using MemoryBuffer::getFileAsStream; 233 using MemoryBuffer::getFileOrSTDIN; 234 using MemoryBuffer::getMemBuffer; 235 using MemoryBuffer::getMemBufferCopy; 236 using MemoryBuffer::getOpenFile; 237 using MemoryBuffer::getOpenFileSlice; 238 using MemoryBuffer::getSTDIN; 239 }; 240 241 /// This class is an extension of MemoryBuffer, which allows write access to 242 /// the underlying contents and committing those changes to the original source. 243 /// It only supports creation methods that are guaranteed to produce a writable 244 /// buffer. For example, mapping a file read-only is not supported. 245 class WriteThroughMemoryBuffer : public MemoryBuffer { 246 protected: 247 WriteThroughMemoryBuffer() = default; 248 249 public: 250 using MemoryBuffer::getBuffer; 251 using MemoryBuffer::getBufferEnd; 252 using MemoryBuffer::getBufferStart; 253 254 // const_cast is well-defined here, because the underlying buffer is 255 // guaranteed to have been initialized with a mutable buffer. getBufferStart()256 char *getBufferStart() { 257 return const_cast<char *>(MemoryBuffer::getBufferStart()); 258 } getBufferEnd()259 char *getBufferEnd() { 260 return const_cast<char *>(MemoryBuffer::getBufferEnd()); 261 } getBuffer()262 MutableArrayRef<char> getBuffer() { 263 return {getBufferStart(), getBufferEnd()}; 264 } 265 266 static ErrorOr<std::unique_ptr<WriteThroughMemoryBuffer>> 267 getFile(const Twine &Filename, int64_t FileSize = -1); 268 269 /// Map a subrange of the specified file as a ReadWriteMemoryBuffer. 270 static ErrorOr<std::unique_ptr<WriteThroughMemoryBuffer>> 271 getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset); 272 273 private: 274 // Hide these base class factory function so one can't write 275 // WritableMemoryBuffer::getXXX() 276 // and be surprised that he got a read-only Buffer. 277 using MemoryBuffer::getFileAsStream; 278 using MemoryBuffer::getFileOrSTDIN; 279 using MemoryBuffer::getMemBuffer; 280 using MemoryBuffer::getMemBufferCopy; 281 using MemoryBuffer::getOpenFile; 282 using MemoryBuffer::getOpenFileSlice; 283 using MemoryBuffer::getSTDIN; 284 }; 285 286 // Create wrappers for C Binding types (see CBindingWrapping.h). 287 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef) 288 289 } // end namespace llvm 290 291 #endif // LLVM_SUPPORT_MEMORYBUFFER_H 292