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