MemoryBuffer.h 11 KB

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