1 //===-- BitReader.cpp -----------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm-c/BitReader.h" 11 #include "llvm/Bitcode/ReaderWriter.h" 12 #include "llvm/IR/DiagnosticPrinter.h" 13 #include "llvm/IR/LLVMContext.h" 14 #include "llvm/IR/Module.h" 15 #include "llvm/Support/MemoryBuffer.h" 16 #include "llvm/Support/raw_ostream.h" 17 #include <cstring> 18 #include <string> 19 20 using namespace llvm; 21 22 /* Builds a module from the bitcode in the specified memory buffer, returning a 23 reference to the module via the OutModule parameter. Returns 0 on success. 24 Optionally returns a human-readable error message via OutMessage. */ 25 LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, 26 LLVMModuleRef *OutModule, char **OutMessage) { 27 return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule, 28 OutMessage); 29 } 30 31 static void diagnosticHandler(const DiagnosticInfo &DI, void *C) { 32 auto *Message = reinterpret_cast<std::string *>(C); 33 raw_string_ostream Stream(*Message); 34 DiagnosticPrinterRawOStream DP(Stream); 35 DI.print(DP); 36 } 37 38 LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, 39 LLVMMemoryBufferRef MemBuf, 40 LLVMModuleRef *OutModule, 41 char **OutMessage) { 42 MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 43 LLVMContext &Ctx = *unwrap(ContextRef); 44 45 LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = 46 Ctx.getDiagnosticHandler(); 47 void *OldDiagnosticContext = Ctx.getDiagnosticContext(); 48 std::string Message; 49 Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true); 50 51 ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 52 53 Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); 54 55 if (ModuleOrErr.getError()) { 56 if (OutMessage) 57 *OutMessage = strdup(Message.c_str()); 58 *OutModule = wrap((Module*)nullptr); 59 return 1; 60 } 61 62 *OutModule = wrap(ModuleOrErr.get().release()); 63 return 0; 64 } 65 66 /* Reads a module from the specified path, returning via the OutModule parameter 67 a module provider which performs lazy deserialization. Returns 0 on success. 68 Optionally returns a human-readable error message via OutMessage. */ 69 LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, 70 LLVMMemoryBufferRef MemBuf, 71 LLVMModuleRef *OutM, 72 char **OutMessage) { 73 std::string Message; 74 std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 75 76 ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 77 getLazyBitcodeModule(std::move(Owner), *unwrap(ContextRef)); 78 Owner.release(); 79 80 if (std::error_code EC = ModuleOrErr.getError()) { 81 *OutM = wrap((Module *)nullptr); 82 if (OutMessage) 83 *OutMessage = strdup(EC.message().c_str()); 84 return 1; 85 } 86 87 *OutM = wrap(ModuleOrErr.get().release()); 88 89 return 0; 90 91 } 92 93 LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 94 char **OutMessage) { 95 return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM, 96 OutMessage); 97 } 98