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" 11*7d523365SDimitry Andric #include "llvm-c/Core.h" 12f22ef01cSRoman Divacky #include "llvm/Bitcode/ReaderWriter.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. */ 26*7d523365SDimitry Andric LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule, 27*7d523365SDimitry Andric char **OutMessage) { 28f22ef01cSRoman Divacky return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule, 29f22ef01cSRoman Divacky OutMessage); 30f22ef01cSRoman Divacky } 31f22ef01cSRoman Divacky 32*7d523365SDimitry Andric LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf, 33*7d523365SDimitry Andric LLVMModuleRef *OutModule) { 34*7d523365SDimitry Andric return LLVMParseBitcodeInContext2(wrap(&getGlobalContext()), MemBuf, 35*7d523365SDimitry Andric OutModule); 36*7d523365SDimitry Andric } 37*7d523365SDimitry Andric 38*7d523365SDimitry Andric static void diagnosticHandler(const DiagnosticInfo &DI, void *C) { 39*7d523365SDimitry Andric auto *Message = reinterpret_cast<std::string *>(C); 40*7d523365SDimitry Andric raw_string_ostream Stream(*Message); 41*7d523365SDimitry Andric DiagnosticPrinterRawOStream DP(Stream); 42*7d523365SDimitry Andric DI.print(DP); 43*7d523365SDimitry Andric } 44*7d523365SDimitry Andric 45f22ef01cSRoman Divacky LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, 46f22ef01cSRoman Divacky LLVMMemoryBufferRef MemBuf, 47f22ef01cSRoman Divacky LLVMModuleRef *OutModule, 48f22ef01cSRoman Divacky char **OutMessage) { 4944f7b0dcSDimitry Andric MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 5044f7b0dcSDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef); 5144f7b0dcSDimitry Andric 52*7d523365SDimitry Andric LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = 53*7d523365SDimitry Andric Ctx.getDiagnosticHandler(); 54*7d523365SDimitry Andric void *OldDiagnosticContext = Ctx.getDiagnosticContext(); 5544f7b0dcSDimitry Andric std::string Message; 56*7d523365SDimitry Andric Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true); 5744f7b0dcSDimitry Andric 58*7d523365SDimitry Andric ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 59*7d523365SDimitry Andric 60*7d523365SDimitry Andric Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); 61*7d523365SDimitry Andric 6244f7b0dcSDimitry Andric if (ModuleOrErr.getError()) { 63*7d523365SDimitry Andric if (OutMessage) 6444f7b0dcSDimitry Andric *OutMessage = strdup(Message.c_str()); 65*7d523365SDimitry Andric *OutModule = wrap((Module *)nullptr); 66*7d523365SDimitry Andric return 1; 6744f7b0dcSDimitry Andric } 68*7d523365SDimitry Andric 69*7d523365SDimitry Andric *OutModule = wrap(ModuleOrErr.get().release()); 70*7d523365SDimitry Andric return 0; 71*7d523365SDimitry Andric } 72*7d523365SDimitry Andric 73*7d523365SDimitry Andric LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef, 74*7d523365SDimitry Andric LLVMMemoryBufferRef MemBuf, 75*7d523365SDimitry Andric LLVMModuleRef *OutModule) { 76*7d523365SDimitry Andric MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 77*7d523365SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef); 78*7d523365SDimitry Andric 79*7d523365SDimitry Andric ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 80*7d523365SDimitry Andric if (ModuleOrErr.getError()) { 8191bc56edSDimitry Andric *OutModule = wrap((Module *)nullptr); 82f22ef01cSRoman Divacky return 1; 83f22ef01cSRoman Divacky } 84f22ef01cSRoman Divacky 858f0fd8f6SDimitry Andric *OutModule = wrap(ModuleOrErr.get().release()); 86f22ef01cSRoman Divacky return 0; 87f22ef01cSRoman Divacky } 88f22ef01cSRoman Divacky 89f22ef01cSRoman Divacky /* Reads a module from the specified path, returning via the OutModule parameter 90f22ef01cSRoman Divacky a module provider which performs lazy deserialization. Returns 0 on success. 91f22ef01cSRoman Divacky Optionally returns a human-readable error message via OutMessage. */ 92f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, 93f22ef01cSRoman Divacky LLVMMemoryBufferRef MemBuf, 94*7d523365SDimitry Andric LLVMModuleRef *OutM, char **OutMessage) { 95*7d523365SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef); 96*7d523365SDimitry Andric LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = 97*7d523365SDimitry Andric Ctx.getDiagnosticHandler(); 98*7d523365SDimitry Andric void *OldDiagnosticContext = Ctx.getDiagnosticContext(); 99*7d523365SDimitry Andric 100f22ef01cSRoman Divacky std::string Message; 101*7d523365SDimitry Andric Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true); 10239d628a0SDimitry Andric std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 10339d628a0SDimitry Andric 1048f0fd8f6SDimitry Andric ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 105*7d523365SDimitry Andric getLazyBitcodeModule(std::move(Owner), Ctx); 10639d628a0SDimitry Andric Owner.release(); 107*7d523365SDimitry Andric Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); 108f22ef01cSRoman Divacky 109*7d523365SDimitry Andric if (ModuleOrErr.getError()) { 11091bc56edSDimitry Andric *OutM = wrap((Module *)nullptr); 111f22ef01cSRoman Divacky if (OutMessage) 112*7d523365SDimitry Andric *OutMessage = strdup(Message.c_str()); 113f22ef01cSRoman Divacky return 1; 114f22ef01cSRoman Divacky } 115f22ef01cSRoman Divacky 1168f0fd8f6SDimitry Andric *OutM = wrap(ModuleOrErr.get().release()); 11791bc56edSDimitry Andric 118f22ef01cSRoman Divacky return 0; 119*7d523365SDimitry Andric } 120f22ef01cSRoman Divacky 121*7d523365SDimitry Andric LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef, 122*7d523365SDimitry Andric LLVMMemoryBufferRef MemBuf, 123*7d523365SDimitry Andric LLVMModuleRef *OutM) { 124*7d523365SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef); 125*7d523365SDimitry Andric std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 126*7d523365SDimitry Andric 127*7d523365SDimitry Andric ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 128*7d523365SDimitry Andric getLazyBitcodeModule(std::move(Owner), Ctx); 129*7d523365SDimitry Andric Owner.release(); 130*7d523365SDimitry Andric 131*7d523365SDimitry Andric if (ModuleOrErr.getError()) { 132*7d523365SDimitry Andric *OutM = wrap((Module *)nullptr); 133*7d523365SDimitry Andric return 1; 134*7d523365SDimitry Andric } 135*7d523365SDimitry Andric 136*7d523365SDimitry Andric *OutM = wrap(ModuleOrErr.get().release()); 137*7d523365SDimitry Andric return 0; 138f22ef01cSRoman Divacky } 139f22ef01cSRoman Divacky 140f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 141f22ef01cSRoman Divacky char **OutMessage) { 142f22ef01cSRoman Divacky return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM, 143f22ef01cSRoman Divacky OutMessage); 144f22ef01cSRoman Divacky } 145f22ef01cSRoman Divacky 146*7d523365SDimitry Andric LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf, 147*7d523365SDimitry Andric LLVMModuleRef *OutM) { 148*7d523365SDimitry Andric return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM); 149f22ef01cSRoman Divacky } 150