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