LCOV - code coverage report
Current view: top level - include/llvm/Support - MemoryBuffer.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 10 10 100.0 %
Date: 2018-06-17 00:07:59 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13