12b0eed27SGordon Henriksen //===-- BitReader.cpp -----------------------------------------------------===// 22b0eed27SGordon Henriksen // 32b0eed27SGordon Henriksen // The LLVM Compiler Infrastructure 42b0eed27SGordon Henriksen // 5f3ebc3f3SChris Lattner // This file is distributed under the University of Illinois Open Source 6f3ebc3f3SChris Lattner // License. See LICENSE.TXT for details. 72b0eed27SGordon Henriksen // 82b0eed27SGordon Henriksen //===----------------------------------------------------------------------===// 92b0eed27SGordon Henriksen 102b0eed27SGordon Henriksen #include "llvm-c/BitReader.h" 112b0eed27SGordon Henriksen #include "llvm/Bitcode/ReaderWriter.h" 123ee23a9eSRafael Espindola #include "llvm/IR/DiagnosticPrinter.h" 139fb823bbSChandler Carruth #include "llvm/IR/LLVMContext.h" 14dec20e43SFilip Pizlo #include "llvm/IR/Module.h" 152b0eed27SGordon Henriksen #include "llvm/Support/MemoryBuffer.h" 163ee23a9eSRafael Espindola #include "llvm/Support/raw_ostream.h" 17579f0713SAnton Korobeynikov #include <cstring> 18ed0881b2SChandler Carruth #include <string> 192b0eed27SGordon Henriksen 202b0eed27SGordon Henriksen using namespace llvm; 212b0eed27SGordon Henriksen 2234eb6d87SGordon Henriksen /* Builds a module from the bitcode in the specified memory buffer, returning a 2334eb6d87SGordon Henriksen reference to the module via the OutModule parameter. Returns 0 on success. 2434eb6d87SGordon Henriksen Optionally returns a human-readable error message via OutMessage. */ 2525963c61SChris Lattner LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, 2631d44e49SOwen Anderson LLVMModuleRef *OutModule, char **OutMessage) { 27754946c1SDaniel Dunbar return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule, 28754946c1SDaniel Dunbar OutMessage); 2931d44e49SOwen Anderson } 3031d44e49SOwen Anderson 31*9d2bfc48SRafael Espindola static void diagnosticHandler(const DiagnosticInfo &DI, void *C) { 32*9d2bfc48SRafael Espindola auto *Message = reinterpret_cast<std::string *>(C); 33*9d2bfc48SRafael Espindola raw_string_ostream Stream(*Message); 34*9d2bfc48SRafael Espindola DiagnosticPrinterRawOStream DP(Stream); 35*9d2bfc48SRafael Espindola DI.print(DP); 36*9d2bfc48SRafael Espindola } 37*9d2bfc48SRafael Espindola 3825963c61SChris Lattner LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, 3970ede484SErick Tryzelaar LLVMMemoryBufferRef MemBuf, 4025963c61SChris Lattner LLVMModuleRef *OutModule, 4125963c61SChris Lattner char **OutMessage) { 423ee23a9eSRafael Espindola MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 433ee23a9eSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 443ee23a9eSRafael Espindola 45*9d2bfc48SRafael Espindola LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = 46*9d2bfc48SRafael Espindola Ctx.getDiagnosticHandler(); 47*9d2bfc48SRafael Espindola void *OldDiagnosticContext = Ctx.getDiagnosticContext(); 483ee23a9eSRafael Espindola std::string Message; 49*9d2bfc48SRafael Espindola Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true); 503ee23a9eSRafael Espindola 51*9d2bfc48SRafael Espindola ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 52*9d2bfc48SRafael Espindola 53*9d2bfc48SRafael Espindola Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); 54*9d2bfc48SRafael Espindola 55dcfd6ed1SRafael Espindola if (ModuleOrErr.getError()) { 56*9d2bfc48SRafael Espindola if (OutMessage) 57dcfd6ed1SRafael Espindola *OutMessage = strdup(Message.c_str()); 582617dcceSCraig Topper *OutModule = wrap((Module*)nullptr); 592b0eed27SGordon Henriksen return 1; 602b0eed27SGordon Henriksen } 612b0eed27SGordon Henriksen 62dcd1dca2SRafael Espindola *OutModule = wrap(ModuleOrErr.get().release()); 632b0eed27SGordon Henriksen return 0; 642b0eed27SGordon Henriksen } 652b0eed27SGordon Henriksen 6634eb6d87SGordon Henriksen /* Reads a module from the specified path, returning via the OutModule parameter 6734eb6d87SGordon Henriksen a module provider which performs lazy deserialization. Returns 0 on success. 6834eb6d87SGordon Henriksen Optionally returns a human-readable error message via OutMessage. */ 69ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, 7070ede484SErick Tryzelaar LLVMMemoryBufferRef MemBuf, 71ad0e0cb0SErick Tryzelaar LLVMModuleRef *OutM, 7231d44e49SOwen Anderson char **OutMessage) { 7331d44e49SOwen Anderson std::string Message; 74e2c1d77fSRafael Espindola std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 75e2c1d77fSRafael Espindola 76dcd1dca2SRafael Espindola ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 7768812157SRafael Espindola getLazyBitcodeModule(std::move(Owner), *unwrap(ContextRef)); 78e2c1d77fSRafael Espindola Owner.release(); 7931d44e49SOwen Anderson 80db4ed0bdSRafael Espindola if (std::error_code EC = ModuleOrErr.getError()) { 812617dcceSCraig Topper *OutM = wrap((Module *)nullptr); 8234eb6d87SGordon Henriksen if (OutMessage) 835b6c1e8eSRafael Espindola *OutMessage = strdup(EC.message().c_str()); 8434eb6d87SGordon Henriksen return 1; 8534eb6d87SGordon Henriksen } 8634eb6d87SGordon Henriksen 87dcd1dca2SRafael Espindola *OutM = wrap(ModuleOrErr.get().release()); 885b6c1e8eSRafael Espindola 8934eb6d87SGordon Henriksen return 0; 90ad0e0cb0SErick Tryzelaar 91ad0e0cb0SErick Tryzelaar } 92ad0e0cb0SErick Tryzelaar 93ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 94ad0e0cb0SErick Tryzelaar char **OutMessage) { 95ad0e0cb0SErick Tryzelaar return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM, 96ad0e0cb0SErick Tryzelaar OutMessage); 97ad0e0cb0SErick Tryzelaar } 98ad0e0cb0SErick Tryzelaar 99ad0e0cb0SErick Tryzelaar /* Deprecated: Use LLVMGetBitcodeModuleInContext instead. */ 100ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef, 101ad0e0cb0SErick Tryzelaar LLVMMemoryBufferRef MemBuf, 102ad0e0cb0SErick Tryzelaar LLVMModuleProviderRef *OutMP, 103ad0e0cb0SErick Tryzelaar char **OutMessage) { 104ad0e0cb0SErick Tryzelaar return LLVMGetBitcodeModuleInContext(ContextRef, MemBuf, 105ad0e0cb0SErick Tryzelaar reinterpret_cast<LLVMModuleRef*>(OutMP), 106ad0e0cb0SErick Tryzelaar OutMessage); 107ad0e0cb0SErick Tryzelaar } 108ad0e0cb0SErick Tryzelaar 109ad0e0cb0SErick Tryzelaar /* Deprecated: Use LLVMGetBitcodeModule instead. */ 110ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf, 111ad0e0cb0SErick Tryzelaar LLVMModuleProviderRef *OutMP, 112ad0e0cb0SErick Tryzelaar char **OutMessage) { 113ad0e0cb0SErick Tryzelaar return LLVMGetBitcodeModuleProviderInContext(LLVMGetGlobalContext(), MemBuf, 114ad0e0cb0SErick Tryzelaar OutMP, OutMessage); 1152b0eed27SGordon Henriksen } 116