1f22ef01cSRoman Divacky //===-- BitReader.cpp -----------------------------------------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky 
10f22ef01cSRoman Divacky #include "llvm-c/BitReader.h"
117d523365SDimitry Andric #include "llvm-c/Core.h"
12*d88c1a5aSDimitry Andric #include "llvm/Bitcode/BitcodeReader.h"
1344f7b0dcSDimitry Andric #include "llvm/IR/DiagnosticPrinter.h"
14139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h"
15284c1978SDimitry Andric #include "llvm/IR/Module.h"
16f22ef01cSRoman Divacky #include "llvm/Support/MemoryBuffer.h"
1744f7b0dcSDimitry Andric #include "llvm/Support/raw_ostream.h"
18f22ef01cSRoman Divacky #include <cstring>
19139f7f9bSDimitry Andric #include <string>
20f22ef01cSRoman Divacky 
21f22ef01cSRoman Divacky using namespace llvm;
22f22ef01cSRoman Divacky 
23f22ef01cSRoman Divacky /* Builds a module from the bitcode in the specified memory buffer, returning a
24f22ef01cSRoman Divacky    reference to the module via the OutModule parameter. Returns 0 on success.
25f22ef01cSRoman Divacky    Optionally returns a human-readable error message via OutMessage. */
267d523365SDimitry Andric LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule,
277d523365SDimitry Andric                           char **OutMessage) {
283ca95b02SDimitry Andric   return LLVMParseBitcodeInContext(LLVMGetGlobalContext(), MemBuf, OutModule,
29f22ef01cSRoman Divacky                                    OutMessage);
30f22ef01cSRoman Divacky }
31f22ef01cSRoman Divacky 
327d523365SDimitry Andric LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,
337d523365SDimitry Andric                            LLVMModuleRef *OutModule) {
343ca95b02SDimitry Andric   return LLVMParseBitcodeInContext2(LLVMGetGlobalContext(), MemBuf, OutModule);
357d523365SDimitry Andric }
367d523365SDimitry Andric 
37f22ef01cSRoman Divacky LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
38f22ef01cSRoman Divacky                                    LLVMMemoryBufferRef MemBuf,
39f22ef01cSRoman Divacky                                    LLVMModuleRef *OutModule,
40f22ef01cSRoman Divacky                                    char **OutMessage) {
4144f7b0dcSDimitry Andric   MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
4244f7b0dcSDimitry Andric   LLVMContext &Ctx = *unwrap(ContextRef);
4344f7b0dcSDimitry Andric 
44*d88c1a5aSDimitry Andric   Expected<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
45*d88c1a5aSDimitry Andric   if (Error Err = ModuleOrErr.takeError()) {
4644f7b0dcSDimitry Andric     std::string Message;
47*d88c1a5aSDimitry Andric     handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
48*d88c1a5aSDimitry Andric       Message = EIB.message();
49*d88c1a5aSDimitry Andric     });
507d523365SDimitry Andric     if (OutMessage)
5144f7b0dcSDimitry Andric       *OutMessage = strdup(Message.c_str());
527d523365SDimitry Andric     *OutModule = wrap((Module *)nullptr);
537d523365SDimitry Andric     return 1;
5444f7b0dcSDimitry Andric   }
557d523365SDimitry Andric 
567d523365SDimitry Andric   *OutModule = wrap(ModuleOrErr.get().release());
577d523365SDimitry Andric   return 0;
587d523365SDimitry Andric }
597d523365SDimitry Andric 
607d523365SDimitry Andric LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,
617d523365SDimitry Andric                                     LLVMMemoryBufferRef MemBuf,
627d523365SDimitry Andric                                     LLVMModuleRef *OutModule) {
637d523365SDimitry Andric   MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
647d523365SDimitry Andric   LLVMContext &Ctx = *unwrap(ContextRef);
657d523365SDimitry Andric 
66*d88c1a5aSDimitry Andric   ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
67*d88c1a5aSDimitry Andric       expectedToErrorOrAndEmitErrors(Ctx, parseBitcodeFile(Buf, Ctx));
687d523365SDimitry Andric   if (ModuleOrErr.getError()) {
6991bc56edSDimitry Andric     *OutModule = wrap((Module *)nullptr);
70f22ef01cSRoman Divacky     return 1;
71f22ef01cSRoman Divacky   }
72f22ef01cSRoman Divacky 
738f0fd8f6SDimitry Andric   *OutModule = wrap(ModuleOrErr.get().release());
74f22ef01cSRoman Divacky   return 0;
75f22ef01cSRoman Divacky }
76f22ef01cSRoman Divacky 
77f22ef01cSRoman Divacky /* Reads a module from the specified path, returning via the OutModule parameter
78f22ef01cSRoman Divacky    a module provider which performs lazy deserialization. Returns 0 on success.
79f22ef01cSRoman Divacky    Optionally returns a human-readable error message via OutMessage. */
80f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
81f22ef01cSRoman Divacky                                        LLVMMemoryBufferRef MemBuf,
827d523365SDimitry Andric                                        LLVMModuleRef *OutM, char **OutMessage) {
837d523365SDimitry Andric   LLVMContext &Ctx = *unwrap(ContextRef);
8439d628a0SDimitry Andric   std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
85*d88c1a5aSDimitry Andric   Expected<std::unique_ptr<Module>> ModuleOrErr =
86*d88c1a5aSDimitry Andric       getOwningLazyBitcodeModule(std::move(Owner), Ctx);
87*d88c1a5aSDimitry Andric   // Release the buffer if we didn't take ownership of it since we never owned
88*d88c1a5aSDimitry Andric   // it anyway.
89*d88c1a5aSDimitry Andric   (void)Owner.release();
9039d628a0SDimitry Andric 
91*d88c1a5aSDimitry Andric   if (Error Err = ModuleOrErr.takeError()) {
92*d88c1a5aSDimitry Andric     std::string Message;
93*d88c1a5aSDimitry Andric     handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
94*d88c1a5aSDimitry Andric       Message = EIB.message();
95*d88c1a5aSDimitry Andric     });
96f22ef01cSRoman Divacky     if (OutMessage)
977d523365SDimitry Andric       *OutMessage = strdup(Message.c_str());
98*d88c1a5aSDimitry Andric     *OutM = wrap((Module *)nullptr);
99f22ef01cSRoman Divacky     return 1;
100f22ef01cSRoman Divacky   }
101f22ef01cSRoman Divacky 
1028f0fd8f6SDimitry Andric   *OutM = wrap(ModuleOrErr.get().release());
10391bc56edSDimitry Andric 
104f22ef01cSRoman Divacky   return 0;
1057d523365SDimitry Andric }
106f22ef01cSRoman Divacky 
1077d523365SDimitry Andric LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,
1087d523365SDimitry Andric                                         LLVMMemoryBufferRef MemBuf,
1097d523365SDimitry Andric                                         LLVMModuleRef *OutM) {
1107d523365SDimitry Andric   LLVMContext &Ctx = *unwrap(ContextRef);
1117d523365SDimitry Andric   std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
1127d523365SDimitry Andric 
113*d88c1a5aSDimitry Andric   ErrorOr<std::unique_ptr<Module>> ModuleOrErr = expectedToErrorOrAndEmitErrors(
114*d88c1a5aSDimitry Andric       Ctx, getOwningLazyBitcodeModule(std::move(Owner), Ctx));
1157d523365SDimitry Andric   Owner.release();
1167d523365SDimitry Andric 
1177d523365SDimitry Andric   if (ModuleOrErr.getError()) {
1187d523365SDimitry Andric     *OutM = wrap((Module *)nullptr);
1197d523365SDimitry Andric     return 1;
1207d523365SDimitry Andric   }
1217d523365SDimitry Andric 
1227d523365SDimitry Andric   *OutM = wrap(ModuleOrErr.get().release());
1237d523365SDimitry Andric   return 0;
124f22ef01cSRoman Divacky }
125f22ef01cSRoman Divacky 
126f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
127f22ef01cSRoman Divacky                               char **OutMessage) {
128f22ef01cSRoman Divacky   return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
129f22ef01cSRoman Divacky                                        OutMessage);
130f22ef01cSRoman Divacky }
131f22ef01cSRoman Divacky 
1327d523365SDimitry Andric LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,
1337d523365SDimitry Andric                                LLVMModuleRef *OutM) {
1347d523365SDimitry Andric   return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM);
135f22ef01cSRoman Divacky }
136