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