1 //===-- llvm/Bitcode/ReaderWriter.h - Bitcode reader/writers ----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This header defines interfaces to read and write LLVM bitcode files/streams.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_BITCODE_READERWRITER_H
15 #define LLVM_BITCODE_READERWRITER_H
17 #include "llvm/IR/DiagnosticInfo.h"
18 #include "llvm/Support/ErrorOr.h"
19 #include "llvm/Support/MemoryBuffer.h"
24 class BitstreamWriter;
31 /// Read the header of the specified bitcode buffer and prepare for lazy
32 /// deserialization of function bodies. If successful, this moves Buffer. On
33 /// error, this *does not* move Buffer.
35 getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
37 DiagnosticHandlerFunction DiagnosticHandler = nullptr);
39 /// Read the header of the specified stream and prepare for lazy
40 /// deserialization and streaming of function bodies.
41 ErrorOr<std::unique_ptr<Module>> getStreamedBitcodeModule(
42 StringRef Name, DataStreamer *Streamer, LLVMContext &Context,
43 DiagnosticHandlerFunction DiagnosticHandler = nullptr);
45 /// Read the header of the specified bitcode buffer and extract just the
46 /// triple information. If successful, this returns a string. On error, this
49 getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context,
50 DiagnosticHandlerFunction DiagnosticHandler = nullptr);
52 /// Read the specified bitcode file, returning the module.
54 parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context,
55 DiagnosticHandlerFunction DiagnosticHandler = nullptr);
57 /// WriteBitcodeToFile - Write the specified module to the specified
58 /// raw output stream. For streams where it matters, the given stream
59 /// should be in "binary" mode.
60 void WriteBitcodeToFile(const Module *M, raw_ostream &Out);
63 /// isBitcodeWrapper - Return true if the given bytes are the magic bytes
64 /// for an LLVM IR bitcode wrapper.
66 inline bool isBitcodeWrapper(const unsigned char *BufPtr,
67 const unsigned char *BufEnd) {
68 // See if you can find the hidden message in the magic bytes :-).
69 // (Hint: it's a little-endian encoding.)
70 return BufPtr != BufEnd &&
77 /// isRawBitcode - Return true if the given bytes are the magic bytes for
78 /// raw LLVM IR bitcode (without a wrapper).
80 inline bool isRawBitcode(const unsigned char *BufPtr,
81 const unsigned char *BufEnd) {
82 // These bytes sort of have a hidden message, but it's not in
83 // little-endian this time, and it's a little redundant.
84 return BufPtr != BufEnd &&
91 /// isBitcode - Return true if the given bytes are the magic bytes for
92 /// LLVM IR bitcode, either with or without a wrapper.
94 inline bool isBitcode(const unsigned char *BufPtr,
95 const unsigned char *BufEnd) {
96 return isBitcodeWrapper(BufPtr, BufEnd) ||
97 isRawBitcode(BufPtr, BufEnd);
100 /// SkipBitcodeWrapperHeader - Some systems wrap bc files with a special
101 /// header for padding or other reasons. The format of this header is:
103 /// struct bc_header {
104 /// uint32_t Magic; // 0x0B17C0DE
105 /// uint32_t Version; // Version, currently always 0.
106 /// uint32_t BitcodeOffset; // Offset to traditional bitcode file.
107 /// uint32_t BitcodeSize; // Size of traditional bitcode file.
108 /// ... potentially other gunk ...
111 /// This function is called when we find a file with a matching magic number.
112 /// In this case, skip down to the subsection of the file that is actually a
114 /// If 'VerifyBufferSize' is true, check that the buffer is large enough to
115 /// contain the whole bitcode file.
116 inline bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr,
117 const unsigned char *&BufEnd,
118 bool VerifyBufferSize) {
120 KnownHeaderSize = 4*4, // Size of header we read.
121 OffsetField = 2*4, // Offset in bytes to Offset field.
122 SizeField = 3*4 // Offset in bytes to Size field.
125 // Must contain the header!
126 if (BufEnd-BufPtr < KnownHeaderSize) return true;
128 unsigned Offset = ( BufPtr[OffsetField ] |
129 (BufPtr[OffsetField+1] << 8) |
130 (BufPtr[OffsetField+2] << 16) |
131 (BufPtr[OffsetField+3] << 24));
132 unsigned Size = ( BufPtr[SizeField ] |
133 (BufPtr[SizeField +1] << 8) |
134 (BufPtr[SizeField +2] << 16) |
135 (BufPtr[SizeField +3] << 24));
137 // Verify that Offset+Size fits in the file.
138 if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr))
141 BufEnd = BufPtr+Size;
145 const std::error_category &BitcodeErrorCategory();
146 enum class BitcodeError { InvalidBitcodeSignature, CorruptedBitcode };
147 inline std::error_code make_error_code(BitcodeError E) {
148 return std::error_code(static_cast<int>(E), BitcodeErrorCategory());
151 class BitcodeDiagnosticInfo : public DiagnosticInfo {
156 BitcodeDiagnosticInfo(std::error_code EC, DiagnosticSeverity Severity,
158 void print(DiagnosticPrinter &DP) const override;
159 std::error_code getError() const { return EC; };
161 static bool classof(const DiagnosticInfo *DI) {
162 return DI->getKind() == DK_Bitcode;
166 } // End llvm namespace
169 template <> struct is_error_code_enum<llvm::BitcodeError> : std::true_type {};