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