Use the DiagnosticHandler to print diagnostics when reading bitcode.
[oota-llvm.git] / include / llvm / Bitcode / ReaderWriter.h
1 //===-- llvm/Bitcode/ReaderWriter.h - Bitcode reader/writers ----*- 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 header defines interfaces to read and write LLVM bitcode files/streams.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_BITCODE_READERWRITER_H
15 #define LLVM_BITCODE_READERWRITER_H
16
17 #include "llvm/IR/DiagnosticInfo.h"
18 #include "llvm/Support/ErrorOr.h"
19 #include "llvm/Support/MemoryBuffer.h"
20 #include <memory>
21 #include <string>
22
23 namespace llvm {
24   class BitstreamWriter;
25   class DataStreamer;
26   class LLVMContext;
27   class Module;
28   class ModulePass;
29   class raw_ostream;
30
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.
34   ErrorOr<Module *>
35   getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
36                        LLVMContext &Context,
37                        DiagnosticHandlerFunction DiagnosticHandler = nullptr);
38
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);
44
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
47   /// returns "".
48   std::string
49   getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context,
50                          DiagnosticHandlerFunction DiagnosticHandler = nullptr);
51
52   /// Read the specified bitcode file, returning the module.
53   ErrorOr<Module *>
54   parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context,
55                    DiagnosticHandlerFunction DiagnosticHandler = nullptr);
56
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);
61
62
63   /// isBitcodeWrapper - Return true if the given bytes are the magic bytes
64   /// for an LLVM IR bitcode wrapper.
65   ///
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 &&
71            BufPtr[0] == 0xDE &&
72            BufPtr[1] == 0xC0 &&
73            BufPtr[2] == 0x17 &&
74            BufPtr[3] == 0x0B;
75   }
76
77   /// isRawBitcode - Return true if the given bytes are the magic bytes for
78   /// raw LLVM IR bitcode (without a wrapper).
79   ///
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 &&
85            BufPtr[0] == 'B' &&
86            BufPtr[1] == 'C' &&
87            BufPtr[2] == 0xc0 &&
88            BufPtr[3] == 0xde;
89   }
90
91   /// isBitcode - Return true if the given bytes are the magic bytes for
92   /// LLVM IR bitcode, either with or without a wrapper.
93   ///
94   inline bool isBitcode(const unsigned char *BufPtr,
95                         const unsigned char *BufEnd) {
96     return isBitcodeWrapper(BufPtr, BufEnd) ||
97            isRawBitcode(BufPtr, BufEnd);
98   }
99
100   /// SkipBitcodeWrapperHeader - Some systems wrap bc files with a special
101   /// header for padding or other reasons.  The format of this header is:
102   ///
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 ...
109   /// };
110   ///
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
113   /// BC file.
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) {
119     enum {
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.
123     };
124
125     // Must contain the header!
126     if (BufEnd-BufPtr < KnownHeaderSize) return true;
127
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));
136
137     // Verify that Offset+Size fits in the file.
138     if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr))
139       return true;
140     BufPtr += Offset;
141     BufEnd = BufPtr+Size;
142     return false;
143   }
144
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());
149   }
150
151   class BitcodeDiagnosticInfo : public DiagnosticInfo {
152     const Twine &Msg;
153     std::error_code EC;
154
155   public:
156     BitcodeDiagnosticInfo(std::error_code EC, DiagnosticSeverity Severity,
157                           const Twine &Msg);
158     void print(DiagnosticPrinter &DP) const override;
159     std::error_code getError() const { return EC; };
160
161     static bool classof(const DiagnosticInfo *DI) {
162       return DI->getKind() == DK_Bitcode;
163     }
164   };
165
166 } // End llvm namespace
167
168 namespace std {
169 template <> struct is_error_code_enum<llvm::BitcodeError> : std::true_type {};
170 }
171
172 #endif