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" 12ad17679aSTeresa Johnson #include "llvm/Bitcode/BitcodeReader.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 3725963c61SChris Lattner LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, 3870ede484SErick Tryzelaar LLVMMemoryBufferRef MemBuf, 3925963c61SChris Lattner LLVMModuleRef *OutModule, 4025963c61SChris Lattner char **OutMessage) { 413ee23a9eSRafael Espindola MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 423ee23a9eSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 433ee23a9eSRafael Espindola 44d9445c49SPeter Collingbourne Expected<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 45d9445c49SPeter Collingbourne if (Error Err = ModuleOrErr.takeError()) { 463ee23a9eSRafael Espindola std::string Message; 47d9445c49SPeter Collingbourne handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { 48d9445c49SPeter Collingbourne Message = EIB.message(); 49d9445c49SPeter Collingbourne }); 509d2bfc48SRafael Espindola if (OutMessage) 51dcfd6ed1SRafael Espindola *OutMessage = strdup(Message.c_str()); 522617dcceSCraig Topper *OutModule = wrap((Module *)nullptr); 532b0eed27SGordon Henriksen return 1; 542b0eed27SGordon Henriksen } 552b0eed27SGordon Henriksen 56dcd1dca2SRafael Espindola *OutModule = wrap(ModuleOrErr.get().release()); 572b0eed27SGordon Henriksen return 0; 582b0eed27SGordon Henriksen } 592b0eed27SGordon Henriksen 602339ffedSRafael Espindola LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef, 612339ffedSRafael Espindola LLVMMemoryBufferRef MemBuf, 622339ffedSRafael Espindola LLVMModuleRef *OutModule) { 632339ffedSRafael Espindola MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 642339ffedSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 652339ffedSRafael Espindola 66d9445c49SPeter Collingbourne ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 67d9445c49SPeter Collingbourne expectedToErrorOrAndEmitErrors(Ctx, parseBitcodeFile(Buf, Ctx)); 682339ffedSRafael Espindola if (ModuleOrErr.getError()) { 692339ffedSRafael Espindola *OutModule = wrap((Module *)nullptr); 702339ffedSRafael Espindola return 1; 712339ffedSRafael Espindola } 722339ffedSRafael Espindola 732339ffedSRafael Espindola *OutModule = wrap(ModuleOrErr.get().release()); 742339ffedSRafael Espindola return 0; 752339ffedSRafael Espindola } 762339ffedSRafael Espindola 7734eb6d87SGordon Henriksen /* Reads a module from the specified path, returning via the OutModule parameter 7834eb6d87SGordon Henriksen a module provider which performs lazy deserialization. Returns 0 on success. 7934eb6d87SGordon Henriksen Optionally returns a human-readable error message via OutMessage. */ 80ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, 8170ede484SErick Tryzelaar LLVMMemoryBufferRef MemBuf, 82d7f9c250SRafael Espindola LLVMModuleRef *OutM, char **OutMessage) { 83f382b883SRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 84e2c1d77fSRafael Espindola std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 85d9445c49SPeter Collingbourne Expected<std::unique_ptr<Module>> ModuleOrErr = 86e2dcf7c3SPeter Collingbourne getOwningLazyBitcodeModule(std::move(Owner), Ctx); 87*c79c9d85SEric Fiselier // Release the buffer if we didn't take ownership of it since we never owned 88*c79c9d85SEric Fiselier // it anyway. 89*c79c9d85SEric Fiselier (void)Owner.release(); 9031d44e49SOwen Anderson 91d9445c49SPeter Collingbourne if (Error Err = ModuleOrErr.takeError()) { 92d9445c49SPeter Collingbourne std::string Message; 93d9445c49SPeter Collingbourne handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { 94d9445c49SPeter Collingbourne Message = EIB.message(); 95d9445c49SPeter Collingbourne }); 9634eb6d87SGordon Henriksen if (OutMessage) 97f382b883SRafael Espindola *OutMessage = strdup(Message.c_str()); 98d9445c49SPeter Collingbourne *OutM = wrap((Module *)nullptr); 9934eb6d87SGordon Henriksen return 1; 10034eb6d87SGordon Henriksen } 10134eb6d87SGordon Henriksen 102dcd1dca2SRafael Espindola *OutM = wrap(ModuleOrErr.get().release()); 1035b6c1e8eSRafael Espindola 10434eb6d87SGordon Henriksen return 0; 105ad0e0cb0SErick Tryzelaar } 106ad0e0cb0SErick Tryzelaar 1072339ffedSRafael Espindola LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef, 1082339ffedSRafael Espindola LLVMMemoryBufferRef MemBuf, 1092339ffedSRafael Espindola LLVMModuleRef *OutM) { 1102339ffedSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 1112339ffedSRafael Espindola std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 1122339ffedSRafael Espindola 113d9445c49SPeter Collingbourne ErrorOr<std::unique_ptr<Module>> ModuleOrErr = expectedToErrorOrAndEmitErrors( 114d9445c49SPeter Collingbourne Ctx, getOwningLazyBitcodeModule(std::move(Owner), Ctx)); 1152339ffedSRafael Espindola Owner.release(); 1162339ffedSRafael Espindola 1172339ffedSRafael Espindola if (ModuleOrErr.getError()) { 1182339ffedSRafael Espindola *OutM = wrap((Module *)nullptr); 1192339ffedSRafael Espindola return 1; 1202339ffedSRafael Espindola } 1212339ffedSRafael Espindola 1222339ffedSRafael Espindola *OutM = wrap(ModuleOrErr.get().release()); 1232339ffedSRafael Espindola return 0; 1242339ffedSRafael Espindola } 1252339ffedSRafael Espindola 126ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 127ad0e0cb0SErick Tryzelaar char **OutMessage) { 128ad0e0cb0SErick Tryzelaar return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM, 129ad0e0cb0SErick Tryzelaar OutMessage); 130ad0e0cb0SErick Tryzelaar } 1312339ffedSRafael Espindola 1322339ffedSRafael Espindola LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf, 1332339ffedSRafael Espindola LLVMModuleRef *OutM) { 1342339ffedSRafael Espindola return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM); 1352339ffedSRafael Espindola } 136