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-c/Core.h" 12 #include "llvm/Bitcode/ReaderWriter.h" 13 #include "llvm/IR/DiagnosticPrinter.h" 14 #include "llvm/IR/LLVMContext.h" 15 #include "llvm/IR/Module.h" 16 #include "llvm/Support/MemoryBuffer.h" 17 #include "llvm/Support/raw_ostream.h" 18 #include <cstring> 19 #include <string> 20 21 using namespace llvm; 22 23 /* Builds a module from the bitcode in the specified memory buffer, returning a 24 reference to the module via the OutModule parameter. Returns 0 on success. 25 Optionally returns a human-readable error message via OutMessage. */ 26 LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule, 27 char **OutMessage) { 28 return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule, 29 OutMessage); 30 } 31 32 LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf, 33 LLVMModuleRef *OutModule) { 34 return LLVMParseBitcodeInContext2(wrap(&getGlobalContext()), MemBuf, 35 OutModule); 36 } 37 38 static void diagnosticHandler(const DiagnosticInfo &DI, void *C) { 39 auto *Message = reinterpret_cast<std::string *>(C); 40 raw_string_ostream Stream(*Message); 41 DiagnosticPrinterRawOStream DP(Stream); 42 DI.print(DP); 43 } 44 45 LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, 46 LLVMMemoryBufferRef MemBuf, 47 LLVMModuleRef *OutModule, 48 char **OutMessage) { 49 MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 50 LLVMContext &Ctx = *unwrap(ContextRef); 51 52 LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = 53 Ctx.getDiagnosticHandler(); 54 void *OldDiagnosticContext = Ctx.getDiagnosticContext(); 55 std::string Message; 56 Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true); 57 58 ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 59 60 Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); 61 62 if (ModuleOrErr.getError()) { 63 if (OutMessage) 64 *OutMessage = strdup(Message.c_str()); 65 *OutModule = wrap((Module *)nullptr); 66 return 1; 67 } 68 69 *OutModule = wrap(ModuleOrErr.get().release()); 70 return 0; 71 } 72 73 LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef, 74 LLVMMemoryBufferRef MemBuf, 75 LLVMModuleRef *OutModule) { 76 MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 77 LLVMContext &Ctx = *unwrap(ContextRef); 78 79 ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 80 if (ModuleOrErr.getError()) { 81 *OutModule = wrap((Module *)nullptr); 82 return 1; 83 } 84 85 *OutModule = wrap(ModuleOrErr.get().release()); 86 return 0; 87 } 88 89 /* Reads a module from the specified path, returning via the OutModule parameter 90 a module provider which performs lazy deserialization. Returns 0 on success. 91 Optionally returns a human-readable error message via OutMessage. */ 92 LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, 93 LLVMMemoryBufferRef MemBuf, 94 LLVMModuleRef *OutM, char **OutMessage) { 95 LLVMContext &Ctx = *unwrap(ContextRef); 96 LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = 97 Ctx.getDiagnosticHandler(); 98 void *OldDiagnosticContext = Ctx.getDiagnosticContext(); 99 100 std::string Message; 101 Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true); 102 std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 103 104 ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 105 getLazyBitcodeModule(std::move(Owner), Ctx); 106 Owner.release(); 107 Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); 108 109 if (ModuleOrErr.getError()) { 110 *OutM = wrap((Module *)nullptr); 111 if (OutMessage) 112 *OutMessage = strdup(Message.c_str()); 113 return 1; 114 } 115 116 *OutM = wrap(ModuleOrErr.get().release()); 117 118 return 0; 119 } 120 121 LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef, 122 LLVMMemoryBufferRef MemBuf, 123 LLVMModuleRef *OutM) { 124 LLVMContext &Ctx = *unwrap(ContextRef); 125 std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 126 127 ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 128 getLazyBitcodeModule(std::move(Owner), Ctx); 129 Owner.release(); 130 131 if (ModuleOrErr.getError()) { 132 *OutM = wrap((Module *)nullptr); 133 return 1; 134 } 135 136 *OutM = wrap(ModuleOrErr.get().release()); 137 return 0; 138 } 139 140 LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 141 char **OutMessage) { 142 return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM, 143 OutMessage); 144 } 145 146 LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf, 147 LLVMModuleRef *OutM) { 148 return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM); 149 } 150