12b0eed27SGordon Henriksen //===-- BitReader.cpp -----------------------------------------------------===// 22b0eed27SGordon Henriksen // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 62b0eed27SGordon Henriksen // 72b0eed27SGordon Henriksen //===----------------------------------------------------------------------===// 82b0eed27SGordon Henriksen 92b0eed27SGordon Henriksen #include "llvm-c/BitReader.h" 10a6b96004SEric Christopher #include "llvm-c/Core.h" 11ad17679aSTeresa Johnson #include "llvm/Bitcode/BitcodeReader.h" 129fb823bbSChandler Carruth #include "llvm/IR/LLVMContext.h" 13dec20e43SFilip Pizlo #include "llvm/IR/Module.h" 142b0eed27SGordon Henriksen #include "llvm/Support/MemoryBuffer.h" 153ee23a9eSRafael Espindola #include "llvm/Support/raw_ostream.h" 16579f0713SAnton Korobeynikov #include <cstring> 17ed0881b2SChandler Carruth #include <string> 182b0eed27SGordon Henriksen 192b0eed27SGordon Henriksen using namespace llvm; 202b0eed27SGordon Henriksen 2134eb6d87SGordon Henriksen /* Builds a module from the bitcode in the specified memory buffer, returning a 2234eb6d87SGordon Henriksen reference to the module via the OutModule parameter. Returns 0 on success. 2334eb6d87SGordon Henriksen Optionally returns a human-readable error message via OutMessage. */ 24d7f9c250SRafael Espindola LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule, 25d7f9c250SRafael Espindola char **OutMessage) { 2603b42e41SMehdi Amini return LLVMParseBitcodeInContext(LLVMGetGlobalContext(), MemBuf, OutModule, 27754946c1SDaniel Dunbar OutMessage); 2831d44e49SOwen Anderson } 2931d44e49SOwen Anderson 302339ffedSRafael Espindola LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf, 312339ffedSRafael Espindola LLVMModuleRef *OutModule) { 3203b42e41SMehdi Amini return LLVMParseBitcodeInContext2(LLVMGetGlobalContext(), MemBuf, OutModule); 332339ffedSRafael Espindola } 342339ffedSRafael Espindola 3525963c61SChris Lattner LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, 3670ede484SErick Tryzelaar LLVMMemoryBufferRef MemBuf, 3725963c61SChris Lattner LLVMModuleRef *OutModule, 3825963c61SChris Lattner char **OutMessage) { 393ee23a9eSRafael Espindola MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 403ee23a9eSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 413ee23a9eSRafael Espindola 42d9445c49SPeter Collingbourne Expected<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 43d9445c49SPeter Collingbourne if (Error Err = ModuleOrErr.takeError()) { 443ee23a9eSRafael Espindola std::string Message; 45d9445c49SPeter Collingbourne handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { 46d9445c49SPeter Collingbourne Message = EIB.message(); 47d9445c49SPeter Collingbourne }); 489d2bfc48SRafael Espindola if (OutMessage) 49dcfd6ed1SRafael Espindola *OutMessage = strdup(Message.c_str()); 502617dcceSCraig Topper *OutModule = wrap((Module *)nullptr); 512b0eed27SGordon Henriksen return 1; 522b0eed27SGordon Henriksen } 532b0eed27SGordon Henriksen 54dcd1dca2SRafael Espindola *OutModule = wrap(ModuleOrErr.get().release()); 552b0eed27SGordon Henriksen return 0; 562b0eed27SGordon Henriksen } 572b0eed27SGordon Henriksen 582339ffedSRafael Espindola LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef, 592339ffedSRafael Espindola LLVMMemoryBufferRef MemBuf, 602339ffedSRafael Espindola LLVMModuleRef *OutModule) { 612339ffedSRafael Espindola MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 622339ffedSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 632339ffedSRafael Espindola 64d9445c49SPeter Collingbourne ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 65d9445c49SPeter Collingbourne expectedToErrorOrAndEmitErrors(Ctx, parseBitcodeFile(Buf, Ctx)); 662339ffedSRafael Espindola if (ModuleOrErr.getError()) { 672339ffedSRafael Espindola *OutModule = wrap((Module *)nullptr); 682339ffedSRafael Espindola return 1; 692339ffedSRafael Espindola } 702339ffedSRafael Espindola 712339ffedSRafael Espindola *OutModule = wrap(ModuleOrErr.get().release()); 722339ffedSRafael Espindola return 0; 732339ffedSRafael Espindola } 742339ffedSRafael Espindola 7534eb6d87SGordon Henriksen /* Reads a module from the specified path, returning via the OutModule parameter 7634eb6d87SGordon Henriksen a module provider which performs lazy deserialization. Returns 0 on success. 7734eb6d87SGordon Henriksen Optionally returns a human-readable error message via OutMessage. */ 78ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, 7970ede484SErick Tryzelaar LLVMMemoryBufferRef MemBuf, 80d7f9c250SRafael Espindola LLVMModuleRef *OutM, char **OutMessage) { 81f382b883SRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 82e2c1d77fSRafael Espindola std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 83d9445c49SPeter Collingbourne Expected<std::unique_ptr<Module>> ModuleOrErr = 84e2dcf7c3SPeter Collingbourne getOwningLazyBitcodeModule(std::move(Owner), Ctx); 85c79c9d85SEric Fiselier // Release the buffer if we didn't take ownership of it since we never owned 86c79c9d85SEric Fiselier // it anyway. 87c79c9d85SEric Fiselier (void)Owner.release(); 8831d44e49SOwen Anderson 89d9445c49SPeter Collingbourne if (Error Err = ModuleOrErr.takeError()) { 90d9445c49SPeter Collingbourne std::string Message; 91d9445c49SPeter Collingbourne handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { 92d9445c49SPeter Collingbourne Message = EIB.message(); 93d9445c49SPeter Collingbourne }); 9434eb6d87SGordon Henriksen if (OutMessage) 95f382b883SRafael Espindola *OutMessage = strdup(Message.c_str()); 96d9445c49SPeter Collingbourne *OutM = wrap((Module *)nullptr); 9734eb6d87SGordon Henriksen return 1; 9834eb6d87SGordon Henriksen } 9934eb6d87SGordon Henriksen 100dcd1dca2SRafael Espindola *OutM = wrap(ModuleOrErr.get().release()); 1015b6c1e8eSRafael Espindola 10234eb6d87SGordon Henriksen return 0; 103ad0e0cb0SErick Tryzelaar } 104ad0e0cb0SErick Tryzelaar 1052339ffedSRafael Espindola LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef, 1062339ffedSRafael Espindola LLVMMemoryBufferRef MemBuf, 1072339ffedSRafael Espindola LLVMModuleRef *OutM) { 1082339ffedSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 1092339ffedSRafael Espindola std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 1102339ffedSRafael Espindola 111d9445c49SPeter Collingbourne ErrorOr<std::unique_ptr<Module>> ModuleOrErr = expectedToErrorOrAndEmitErrors( 112d9445c49SPeter Collingbourne Ctx, getOwningLazyBitcodeModule(std::move(Owner), Ctx)); 1132339ffedSRafael Espindola Owner.release(); 1142339ffedSRafael Espindola 1152339ffedSRafael Espindola if (ModuleOrErr.getError()) { 1162339ffedSRafael Espindola *OutM = wrap((Module *)nullptr); 1172339ffedSRafael Espindola return 1; 1182339ffedSRafael Espindola } 1192339ffedSRafael Espindola 1202339ffedSRafael Espindola *OutM = wrap(ModuleOrErr.get().release()); 1212339ffedSRafael Espindola return 0; 1222339ffedSRafael Espindola } 1232339ffedSRafael Espindola 124ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 125ad0e0cb0SErick Tryzelaar char **OutMessage) { 126ad0e0cb0SErick Tryzelaar return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM, 127ad0e0cb0SErick Tryzelaar OutMessage); 128ad0e0cb0SErick Tryzelaar } 1292339ffedSRafael Espindola 1302339ffedSRafael Espindola LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf, 1312339ffedSRafael Espindola LLVMModuleRef *OutM) { 1322339ffedSRafael Espindola return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM); 1332339ffedSRafael Espindola } 134