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" 11f22ef01cSRoman Divacky #include "llvm/Bitcode/ReaderWriter.h" 12*44f7b0dcSDimitry Andric #include "llvm/IR/DiagnosticPrinter.h" 13139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h" 14284c1978SDimitry Andric #include "llvm/IR/Module.h" 15f22ef01cSRoman Divacky #include "llvm/Support/MemoryBuffer.h" 16*44f7b0dcSDimitry 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. */ 25f22ef01cSRoman Divacky LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, 26f22ef01cSRoman Divacky LLVMModuleRef *OutModule, char **OutMessage) { 27f22ef01cSRoman Divacky return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule, 28f22ef01cSRoman Divacky OutMessage); 29f22ef01cSRoman Divacky } 30f22ef01cSRoman Divacky 31f22ef01cSRoman Divacky LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, 32f22ef01cSRoman Divacky LLVMMemoryBufferRef MemBuf, 33f22ef01cSRoman Divacky LLVMModuleRef *OutModule, 34f22ef01cSRoman Divacky char **OutMessage) { 35*44f7b0dcSDimitry Andric MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 36*44f7b0dcSDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef); 37*44f7b0dcSDimitry Andric 38*44f7b0dcSDimitry Andric std::string Message; 39*44f7b0dcSDimitry Andric raw_string_ostream Stream(Message); 40*44f7b0dcSDimitry Andric DiagnosticPrinterRawOStream DP(Stream); 41*44f7b0dcSDimitry Andric 42*44f7b0dcSDimitry Andric ErrorOr<Module *> ModuleOrErr = parseBitcodeFile( 43*44f7b0dcSDimitry Andric Buf, Ctx, [&](const DiagnosticInfo &DI) { DI.print(DP); }); 44*44f7b0dcSDimitry Andric if (ModuleOrErr.getError()) { 45*44f7b0dcSDimitry Andric if (OutMessage) { 46*44f7b0dcSDimitry Andric Stream.flush(); 47*44f7b0dcSDimitry Andric *OutMessage = strdup(Message.c_str()); 48*44f7b0dcSDimitry Andric } 4991bc56edSDimitry Andric *OutModule = wrap((Module*)nullptr); 50f22ef01cSRoman Divacky return 1; 51f22ef01cSRoman Divacky } 52f22ef01cSRoman Divacky 5391bc56edSDimitry Andric *OutModule = wrap(ModuleOrErr.get()); 54f22ef01cSRoman Divacky return 0; 55f22ef01cSRoman Divacky } 56f22ef01cSRoman Divacky 57f22ef01cSRoman Divacky /* Reads a module from the specified path, returning via the OutModule parameter 58f22ef01cSRoman Divacky a module provider which performs lazy deserialization. Returns 0 on success. 59f22ef01cSRoman Divacky Optionally returns a human-readable error message via OutMessage. */ 60f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, 61f22ef01cSRoman Divacky LLVMMemoryBufferRef MemBuf, 62f22ef01cSRoman Divacky LLVMModuleRef *OutM, 63f22ef01cSRoman Divacky char **OutMessage) { 64f22ef01cSRoman Divacky std::string Message; 6539d628a0SDimitry Andric std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 6639d628a0SDimitry Andric 6791bc56edSDimitry Andric ErrorOr<Module *> ModuleOrErr = 6839d628a0SDimitry Andric getLazyBitcodeModule(std::move(Owner), *unwrap(ContextRef)); 6939d628a0SDimitry Andric Owner.release(); 70f22ef01cSRoman Divacky 7191bc56edSDimitry Andric if (std::error_code EC = ModuleOrErr.getError()) { 7291bc56edSDimitry Andric *OutM = wrap((Module *)nullptr); 73f22ef01cSRoman Divacky if (OutMessage) 7491bc56edSDimitry Andric *OutMessage = strdup(EC.message().c_str()); 75f22ef01cSRoman Divacky return 1; 76f22ef01cSRoman Divacky } 77f22ef01cSRoman Divacky 7891bc56edSDimitry Andric *OutM = wrap(ModuleOrErr.get()); 7991bc56edSDimitry Andric 80f22ef01cSRoman Divacky return 0; 81f22ef01cSRoman Divacky 82f22ef01cSRoman Divacky } 83f22ef01cSRoman Divacky 84f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 85f22ef01cSRoman Divacky char **OutMessage) { 86f22ef01cSRoman Divacky return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM, 87f22ef01cSRoman Divacky OutMessage); 88f22ef01cSRoman Divacky } 89f22ef01cSRoman Divacky 90f22ef01cSRoman Divacky /* Deprecated: Use LLVMGetBitcodeModuleInContext instead. */ 91f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef, 92f22ef01cSRoman Divacky LLVMMemoryBufferRef MemBuf, 93f22ef01cSRoman Divacky LLVMModuleProviderRef *OutMP, 94f22ef01cSRoman Divacky char **OutMessage) { 95f22ef01cSRoman Divacky return LLVMGetBitcodeModuleInContext(ContextRef, MemBuf, 96f22ef01cSRoman Divacky reinterpret_cast<LLVMModuleRef*>(OutMP), 97f22ef01cSRoman Divacky OutMessage); 98f22ef01cSRoman Divacky } 99f22ef01cSRoman Divacky 100f22ef01cSRoman Divacky /* Deprecated: Use LLVMGetBitcodeModule instead. */ 101f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf, 102f22ef01cSRoman Divacky LLVMModuleProviderRef *OutMP, 103f22ef01cSRoman Divacky char **OutMessage) { 104f22ef01cSRoman Divacky return LLVMGetBitcodeModuleProviderInContext(LLVMGetGlobalContext(), MemBuf, 105f22ef01cSRoman Divacky OutMP, OutMessage); 106f22ef01cSRoman Divacky } 107