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" 11a6b96004SEric Christopher #include "llvm-c/Core.h" 122b0eed27SGordon Henriksen #include "llvm/Bitcode/ReaderWriter.h" 133ee23a9eSRafael Espindola #include "llvm/IR/DiagnosticPrinter.h" 149fb823bbSChandler Carruth #include "llvm/IR/LLVMContext.h" 15dec20e43SFilip Pizlo #include "llvm/IR/Module.h" 162b0eed27SGordon Henriksen #include "llvm/Support/MemoryBuffer.h" 173ee23a9eSRafael Espindola #include "llvm/Support/raw_ostream.h" 18579f0713SAnton Korobeynikov #include <cstring> 19ed0881b2SChandler Carruth #include <string> 202b0eed27SGordon Henriksen 212b0eed27SGordon Henriksen using namespace llvm; 222b0eed27SGordon Henriksen 2334eb6d87SGordon Henriksen /* Builds a module from the bitcode in the specified memory buffer, returning a 2434eb6d87SGordon Henriksen reference to the module via the OutModule parameter. Returns 0 on success. 2534eb6d87SGordon Henriksen Optionally returns a human-readable error message via OutMessage. */ 26d7f9c250SRafael Espindola LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule, 27d7f9c250SRafael Espindola char **OutMessage) { 2803b42e41SMehdi Amini return LLVMParseBitcodeInContext(LLVMGetGlobalContext(), MemBuf, OutModule, 29754946c1SDaniel Dunbar OutMessage); 3031d44e49SOwen Anderson } 3131d44e49SOwen Anderson 322339ffedSRafael Espindola LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf, 332339ffedSRafael Espindola LLVMModuleRef *OutModule) { 3403b42e41SMehdi Amini return LLVMParseBitcodeInContext2(LLVMGetGlobalContext(), MemBuf, OutModule); 352339ffedSRafael Espindola } 362339ffedSRafael Espindola 379d2bfc48SRafael Espindola static void diagnosticHandler(const DiagnosticInfo &DI, void *C) { 389d2bfc48SRafael Espindola auto *Message = reinterpret_cast<std::string *>(C); 399d2bfc48SRafael Espindola raw_string_ostream Stream(*Message); 409d2bfc48SRafael Espindola DiagnosticPrinterRawOStream DP(Stream); 419d2bfc48SRafael Espindola DI.print(DP); 429d2bfc48SRafael Espindola } 439d2bfc48SRafael Espindola 4425963c61SChris Lattner LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, 4570ede484SErick Tryzelaar LLVMMemoryBufferRef MemBuf, 4625963c61SChris Lattner LLVMModuleRef *OutModule, 4725963c61SChris Lattner char **OutMessage) { 483ee23a9eSRafael Espindola MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 493ee23a9eSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 503ee23a9eSRafael Espindola 519d2bfc48SRafael Espindola LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = 529d2bfc48SRafael Espindola Ctx.getDiagnosticHandler(); 539d2bfc48SRafael Espindola void *OldDiagnosticContext = Ctx.getDiagnosticContext(); 543ee23a9eSRafael Espindola std::string Message; 559d2bfc48SRafael Espindola Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true); 563ee23a9eSRafael Espindola 579d2bfc48SRafael Espindola ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 589d2bfc48SRafael Espindola 599d2bfc48SRafael Espindola Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); 609d2bfc48SRafael Espindola 61dcfd6ed1SRafael Espindola if (ModuleOrErr.getError()) { 629d2bfc48SRafael Espindola if (OutMessage) 63dcfd6ed1SRafael Espindola *OutMessage = strdup(Message.c_str()); 642617dcceSCraig Topper *OutModule = wrap((Module *)nullptr); 652b0eed27SGordon Henriksen return 1; 662b0eed27SGordon Henriksen } 672b0eed27SGordon Henriksen 68dcd1dca2SRafael Espindola *OutModule = wrap(ModuleOrErr.get().release()); 692b0eed27SGordon Henriksen return 0; 702b0eed27SGordon Henriksen } 712b0eed27SGordon Henriksen 722339ffedSRafael Espindola LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef, 732339ffedSRafael Espindola LLVMMemoryBufferRef MemBuf, 742339ffedSRafael Espindola LLVMModuleRef *OutModule) { 752339ffedSRafael Espindola MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 762339ffedSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 772339ffedSRafael Espindola 782339ffedSRafael Espindola ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 792339ffedSRafael Espindola if (ModuleOrErr.getError()) { 802339ffedSRafael Espindola *OutModule = wrap((Module *)nullptr); 812339ffedSRafael Espindola return 1; 822339ffedSRafael Espindola } 832339ffedSRafael Espindola 842339ffedSRafael Espindola *OutModule = wrap(ModuleOrErr.get().release()); 852339ffedSRafael Espindola return 0; 862339ffedSRafael Espindola } 872339ffedSRafael Espindola 8834eb6d87SGordon Henriksen /* Reads a module from the specified path, returning via the OutModule parameter 8934eb6d87SGordon Henriksen a module provider which performs lazy deserialization. Returns 0 on success. 9034eb6d87SGordon Henriksen Optionally returns a human-readable error message via OutMessage. */ 91ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, 9270ede484SErick Tryzelaar LLVMMemoryBufferRef MemBuf, 93d7f9c250SRafael Espindola LLVMModuleRef *OutM, char **OutMessage) { 94f382b883SRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 95f382b883SRafael Espindola LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = 96f382b883SRafael Espindola Ctx.getDiagnosticHandler(); 97f382b883SRafael Espindola void *OldDiagnosticContext = Ctx.getDiagnosticContext(); 98f382b883SRafael Espindola 9931d44e49SOwen Anderson std::string Message; 100f382b883SRafael Espindola Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true); 101e2c1d77fSRafael Espindola std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 102e2c1d77fSRafael Espindola 103dcd1dca2SRafael Espindola ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 104*e2dcf7c3SPeter Collingbourne getOwningLazyBitcodeModule(std::move(Owner), Ctx); 105e2c1d77fSRafael Espindola Owner.release(); 106f382b883SRafael Espindola Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); 10731d44e49SOwen Anderson 108f382b883SRafael Espindola if (ModuleOrErr.getError()) { 1092617dcceSCraig Topper *OutM = wrap((Module *)nullptr); 11034eb6d87SGordon Henriksen if (OutMessage) 111f382b883SRafael Espindola *OutMessage = strdup(Message.c_str()); 11234eb6d87SGordon Henriksen return 1; 11334eb6d87SGordon Henriksen } 11434eb6d87SGordon Henriksen 115dcd1dca2SRafael Espindola *OutM = wrap(ModuleOrErr.get().release()); 1165b6c1e8eSRafael Espindola 11734eb6d87SGordon Henriksen return 0; 118ad0e0cb0SErick Tryzelaar } 119ad0e0cb0SErick Tryzelaar 1202339ffedSRafael Espindola LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef, 1212339ffedSRafael Espindola LLVMMemoryBufferRef MemBuf, 1222339ffedSRafael Espindola LLVMModuleRef *OutM) { 1232339ffedSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 1242339ffedSRafael Espindola std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 1252339ffedSRafael Espindola 1262339ffedSRafael Espindola ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 127*e2dcf7c3SPeter Collingbourne getOwningLazyBitcodeModule(std::move(Owner), Ctx); 1282339ffedSRafael Espindola Owner.release(); 1292339ffedSRafael Espindola 1302339ffedSRafael Espindola if (ModuleOrErr.getError()) { 1312339ffedSRafael Espindola *OutM = wrap((Module *)nullptr); 1322339ffedSRafael Espindola return 1; 1332339ffedSRafael Espindola } 1342339ffedSRafael Espindola 1352339ffedSRafael Espindola *OutM = wrap(ModuleOrErr.get().release()); 1362339ffedSRafael Espindola return 0; 1372339ffedSRafael Espindola } 1382339ffedSRafael Espindola 139ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 140ad0e0cb0SErick Tryzelaar char **OutMessage) { 141ad0e0cb0SErick Tryzelaar return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM, 142ad0e0cb0SErick Tryzelaar OutMessage); 143ad0e0cb0SErick Tryzelaar } 1442339ffedSRafael Espindola 1452339ffedSRafael Espindola LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf, 1462339ffedSRafael Espindola LLVMModuleRef *OutM) { 1472339ffedSRafael Espindola return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM); 1482339ffedSRafael Espindola } 149