Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.  
  66.   const char *getBufferStart() const { return BufferStart; }
  67.   const char *getBufferEnd() const   { return BufferEnd; }
  68.   size_t getBufferSize() const { return BufferEnd-BufferStart; }
  69.  
  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.
  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.
  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.
  192.   char *getBufferStart() {
  193.     return const_cast<char *>(MemoryBuffer::getBufferStart());
  194.   }
  195.   char *getBufferEnd() {
  196.     return const_cast<char *>(MemoryBuffer::getBufferEnd());
  197.   }
  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.
  256.   char *getBufferStart() {
  257.     return const_cast<char *>(MemoryBuffer::getBufferStart());
  258.   }
  259.   char *getBufferEnd() {
  260.     return const_cast<char *>(MemoryBuffer::getBufferEnd());
  261.   }
  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.