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"
13139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h"
14284c1978SDimitry Andric #include "llvm/IR/Module.h"
15f22ef01cSRoman Divacky #include "llvm/Support/MemoryBuffer.h"
1644f7b0dcSDimitry Andric #include "llvm/Support/raw_ostream.h"
17f22ef01cSRoman Divacky #include <cstring>
18139f7f9bSDimitry Andric #include <string>
19f22ef01cSRoman Divacky 
20f22ef01cSRoman Divacky using namespace llvm;
21f22ef01cSRoman Divacky 
22f22ef01cSRoman Divacky /* Builds a module from the bitcode in the specified memory buffer, returning a
23f22ef01cSRoman Divacky    reference to the module via the OutModule parameter. Returns 0 on success.
24f22ef01cSRoman Divacky    Optionally returns a human-readable error message via OutMessage. */
LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule,char ** OutMessage)257d523365SDimitry Andric LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule,
267d523365SDimitry Andric                           char **OutMessage) {
273ca95b02SDimitry Andric   return LLVMParseBitcodeInContext(LLVMGetGlobalContext(), MemBuf, OutModule,
28f22ef01cSRoman Divacky                                    OutMessage);
29f22ef01cSRoman Divacky }
30f22ef01cSRoman Divacky 
LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule)317d523365SDimitry Andric LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,
327d523365SDimitry Andric                            LLVMModuleRef *OutModule) {
333ca95b02SDimitry Andric   return LLVMParseBitcodeInContext2(LLVMGetGlobalContext(), MemBuf, OutModule);
347d523365SDimitry Andric }
357d523365SDimitry Andric 
LLVMParseBitcodeInContext(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule,char ** OutMessage)36f22ef01cSRoman Divacky LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
37f22ef01cSRoman Divacky                                    LLVMMemoryBufferRef MemBuf,
38f22ef01cSRoman Divacky                                    LLVMModuleRef *OutModule,
39f22ef01cSRoman Divacky                                    char **OutMessage) {
4044f7b0dcSDimitry Andric   MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
4144f7b0dcSDimitry Andric   LLVMContext &Ctx = *unwrap(ContextRef);
4244f7b0dcSDimitry Andric 
43*d88c1a5aSDimitry Andric   Expected<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
44*d88c1a5aSDimitry Andric   if (Error Err = ModuleOrErr.takeError()) {
4544f7b0dcSDimitry Andric     std::string Message;
46*d88c1a5aSDimitry Andric     handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
47*d88c1a5aSDimitry Andric       Message = EIB.message();
48*d88c1a5aSDimitry Andric     });
497d523365SDimitry Andric     if (OutMessage)
5044f7b0dcSDimitry Andric       *OutMessage = strdup(Message.c_str());
517d523365SDimitry Andric     *OutModule = wrap((Module *)nullptr);
527d523365SDimitry Andric     return 1;
5344f7b0dcSDimitry Andric   }
547d523365SDimitry Andric 
557d523365SDimitry Andric   *OutModule = wrap(ModuleOrErr.get().release());
567d523365SDimitry Andric   return 0;
577d523365SDimitry Andric }
587d523365SDimitry Andric 
LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule)597d523365SDimitry Andric LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,
607d523365SDimitry Andric                                     LLVMMemoryBufferRef MemBuf,
617d523365SDimitry Andric                                     LLVMModuleRef *OutModule) {
627d523365SDimitry Andric   MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
637d523365SDimitry Andric   LLVMContext &Ctx = *unwrap(ContextRef);
647d523365SDimitry Andric 
65*d88c1a5aSDimitry Andric   ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
66*d88c1a5aSDimitry Andric       expectedToErrorOrAndEmitErrors(Ctx, parseBitcodeFile(Buf, Ctx));
677d523365SDimitry Andric   if (ModuleOrErr.getError()) {
6891bc56edSDimitry Andric     *OutModule = wrap((Module *)nullptr);
69f22ef01cSRoman Divacky     return 1;
70f22ef01cSRoman Divacky   }
71f22ef01cSRoman Divacky 
728f0fd8f6SDimitry Andric   *OutModule = wrap(ModuleOrErr.get().release());
73f22ef01cSRoman Divacky   return 0;
74f22ef01cSRoman Divacky }
75f22ef01cSRoman Divacky 
76f22ef01cSRoman Divacky /* Reads a module from the specified path, returning via the OutModule parameter
77f22ef01cSRoman Divacky    a module provider which performs lazy deserialization. Returns 0 on success.
78f22ef01cSRoman Divacky    Optionally returns a human-readable error message via OutMessage. */
LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM,char ** OutMessage)79f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
80f22ef01cSRoman Divacky                                        LLVMMemoryBufferRef MemBuf,
817d523365SDimitry Andric                                        LLVMModuleRef *OutM, char **OutMessage) {
827d523365SDimitry Andric   LLVMContext &Ctx = *unwrap(ContextRef);
8339d628a0SDimitry Andric   std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
84*d88c1a5aSDimitry Andric   Expected<std::unique_ptr<Module>> ModuleOrErr =
85*d88c1a5aSDimitry Andric       getOwningLazyBitcodeModule(std::move(Owner), Ctx);
86*d88c1a5aSDimitry Andric   // Release the buffer if we didn't take ownership of it since we never owned
87*d88c1a5aSDimitry Andric   // it anyway.
88*d88c1a5aSDimitry Andric   (void)Owner.release();
8939d628a0SDimitry Andric 
90*d88c1a5aSDimitry Andric   if (Error Err = ModuleOrErr.takeError()) {
91*d88c1a5aSDimitry Andric     std::string Message;
92*d88c1a5aSDimitry Andric     handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
93*d88c1a5aSDimitry Andric       Message = EIB.message();
94*d88c1a5aSDimitry Andric     });
95f22ef01cSRoman Divacky     if (OutMessage)
967d523365SDimitry Andric       *OutMessage = strdup(Message.c_str());
97*d88c1a5aSDimitry Andric     *OutM = wrap((Module *)nullptr);
98f22ef01cSRoman Divacky     return 1;
99f22ef01cSRoman Divacky   }
100f22ef01cSRoman Divacky 
1018f0fd8f6SDimitry Andric   *OutM = wrap(ModuleOrErr.get().release());
10291bc56edSDimitry Andric 
103f22ef01cSRoman Divacky   return 0;
1047d523365SDimitry Andric }
105f22ef01cSRoman Divacky 
LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM)1067d523365SDimitry Andric LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,
1077d523365SDimitry Andric                                         LLVMMemoryBufferRef MemBuf,
1087d523365SDimitry Andric                                         LLVMModuleRef *OutM) {
1097d523365SDimitry Andric   LLVMContext &Ctx = *unwrap(ContextRef);
1107d523365SDimitry Andric   std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
1117d523365SDimitry Andric 
112*d88c1a5aSDimitry Andric   ErrorOr<std::unique_ptr<Module>> ModuleOrErr = expectedToErrorOrAndEmitErrors(
113*d88c1a5aSDimitry Andric       Ctx, getOwningLazyBitcodeModule(std::move(Owner), Ctx));
1147d523365SDimitry Andric   Owner.release();
1157d523365SDimitry Andric 
1167d523365SDimitry Andric   if (ModuleOrErr.getError()) {
1177d523365SDimitry Andric     *OutM = wrap((Module *)nullptr);
1187d523365SDimitry Andric     return 1;
1197d523365SDimitry Andric   }
1207d523365SDimitry Andric 
1217d523365SDimitry Andric   *OutM = wrap(ModuleOrErr.get().release());
1227d523365SDimitry Andric   return 0;
123f22ef01cSRoman Divacky }
124f22ef01cSRoman Divacky 
LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM,char ** OutMessage)125f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
126f22ef01cSRoman Divacky                               char **OutMessage) {
127f22ef01cSRoman Divacky   return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
128f22ef01cSRoman Divacky                                        OutMessage);
129f22ef01cSRoman Divacky }
130f22ef01cSRoman Divacky 
LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM)1317d523365SDimitry Andric LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,
1327d523365SDimitry Andric                                LLVMModuleRef *OutM) {
1337d523365SDimitry Andric   return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM);
134f22ef01cSRoman Divacky }
135