1 //===-- BitReader.cpp -----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm-c/BitReader.h" 10 #include "llvm-c/Core.h" 11 #include "llvm/Bitcode/BitcodeReader.h" 12 #include "llvm/IR/LLVMContext.h" 13 #include "llvm/IR/Module.h" 14 #include "llvm/Support/MemoryBuffer.h" 15 #include <cstring> 16 #include <string> 17 18 using namespace llvm; 19 20 /* Builds a module from the bitcode in the specified memory buffer, returning a 21 reference to the module via the OutModule parameter. Returns 0 on success. 22 Optionally returns a human-readable error message via OutMessage. */ 23 LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule, 24 char **OutMessage) { 25 return LLVMParseBitcodeInContext(LLVMGetGlobalContext(), MemBuf, OutModule, 26 OutMessage); 27 } 28 29 LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf, 30 LLVMModuleRef *OutModule) { 31 return LLVMParseBitcodeInContext2(LLVMGetGlobalContext(), MemBuf, OutModule); 32 } 33 34 LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, 35 LLVMMemoryBufferRef MemBuf, 36 LLVMModuleRef *OutModule, 37 char **OutMessage) { 38 MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 39 LLVMContext &Ctx = *unwrap(ContextRef); 40 41 Expected<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 42 if (Error Err = ModuleOrErr.takeError()) { 43 std::string Message; 44 handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { 45 Message = EIB.message(); 46 }); 47 if (OutMessage) 48 *OutMessage = strdup(Message.c_str()); 49 *OutModule = wrap((Module *)nullptr); 50 return 1; 51 } 52 53 *OutModule = wrap(ModuleOrErr.get().release()); 54 return 0; 55 } 56 57 LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef, 58 LLVMMemoryBufferRef MemBuf, 59 LLVMModuleRef *OutModule) { 60 MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 61 LLVMContext &Ctx = *unwrap(ContextRef); 62 63 ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 64 expectedToErrorOrAndEmitErrors(Ctx, parseBitcodeFile(Buf, Ctx)); 65 if (ModuleOrErr.getError()) { 66 *OutModule = wrap((Module *)nullptr); 67 return 1; 68 } 69 70 *OutModule = wrap(ModuleOrErr.get().release()); 71 return 0; 72 } 73 74 /* Reads a module from the specified path, returning via the OutModule parameter 75 a module provider which performs lazy deserialization. Returns 0 on success. 76 Optionally returns a human-readable error message via OutMessage. */ 77 LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, 78 LLVMMemoryBufferRef MemBuf, 79 LLVMModuleRef *OutM, char **OutMessage) { 80 LLVMContext &Ctx = *unwrap(ContextRef); 81 std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 82 Expected<std::unique_ptr<Module>> ModuleOrErr = 83 getOwningLazyBitcodeModule(std::move(Owner), Ctx); 84 // Release the buffer if we didn't take ownership of it since we never owned 85 // it anyway. 86 (void)Owner.release(); 87 88 if (Error Err = ModuleOrErr.takeError()) { 89 std::string Message; 90 handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { 91 Message = EIB.message(); 92 }); 93 if (OutMessage) 94 *OutMessage = strdup(Message.c_str()); 95 *OutM = wrap((Module *)nullptr); 96 return 1; 97 } 98 99 *OutM = wrap(ModuleOrErr.get().release()); 100 101 return 0; 102 } 103 104 LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef, 105 LLVMMemoryBufferRef MemBuf, 106 LLVMModuleRef *OutM) { 107 LLVMContext &Ctx = *unwrap(ContextRef); 108 std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 109 110 ErrorOr<std::unique_ptr<Module>> ModuleOrErr = expectedToErrorOrAndEmitErrors( 111 Ctx, getOwningLazyBitcodeModule(std::move(Owner), Ctx)); 112 Owner.release(); 113 114 if (ModuleOrErr.getError()) { 115 *OutM = wrap((Module *)nullptr); 116 return 1; 117 } 118 119 *OutM = wrap(ModuleOrErr.get().release()); 120 return 0; 121 } 122 123 LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 124 char **OutMessage) { 125 return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM, 126 OutMessage); 127 } 128 129 LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf, 130 LLVMModuleRef *OutM) { 131 return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM); 132 } 133