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