Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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