12b0eed27SGordon Henriksen //===-- BitReader.cpp -----------------------------------------------------===// 22b0eed27SGordon Henriksen // 32b0eed27SGordon Henriksen // The LLVM Compiler Infrastructure 42b0eed27SGordon Henriksen // 5f3ebc3f3SChris Lattner // This file is distributed under the University of Illinois Open Source 6f3ebc3f3SChris Lattner // License. See LICENSE.TXT for details. 72b0eed27SGordon Henriksen // 82b0eed27SGordon Henriksen //===----------------------------------------------------------------------===// 92b0eed27SGordon Henriksen 102b0eed27SGordon Henriksen #include "llvm-c/BitReader.h" 11a6b96004SEric Christopher #include "llvm-c/Core.h" 122b0eed27SGordon Henriksen #include "llvm/Bitcode/ReaderWriter.h" 133ee23a9eSRafael Espindola #include "llvm/IR/DiagnosticPrinter.h" 149fb823bbSChandler Carruth #include "llvm/IR/LLVMContext.h" 15dec20e43SFilip Pizlo #include "llvm/IR/Module.h" 162b0eed27SGordon Henriksen #include "llvm/Support/MemoryBuffer.h" 173ee23a9eSRafael Espindola #include "llvm/Support/raw_ostream.h" 18579f0713SAnton Korobeynikov #include <cstring> 19ed0881b2SChandler Carruth #include <string> 202b0eed27SGordon Henriksen 212b0eed27SGordon Henriksen using namespace llvm; 222b0eed27SGordon Henriksen 2334eb6d87SGordon Henriksen /* Builds a module from the bitcode in the specified memory buffer, returning a 2434eb6d87SGordon Henriksen reference to the module via the OutModule parameter. Returns 0 on success. 2534eb6d87SGordon Henriksen Optionally returns a human-readable error message via OutMessage. */ 26d7f9c250SRafael Espindola LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule, 27d7f9c250SRafael Espindola char **OutMessage) { 28754946c1SDaniel Dunbar return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule, 29754946c1SDaniel Dunbar OutMessage); 3031d44e49SOwen Anderson } 3131d44e49SOwen Anderson 32*2339ffedSRafael Espindola LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf, 33*2339ffedSRafael Espindola LLVMModuleRef *OutModule) { 34*2339ffedSRafael Espindola return LLVMParseBitcodeInContext2(wrap(&getGlobalContext()), MemBuf, 35*2339ffedSRafael Espindola OutModule); 36*2339ffedSRafael Espindola } 37*2339ffedSRafael Espindola 389d2bfc48SRafael Espindola static void diagnosticHandler(const DiagnosticInfo &DI, void *C) { 399d2bfc48SRafael Espindola auto *Message = reinterpret_cast<std::string *>(C); 409d2bfc48SRafael Espindola raw_string_ostream Stream(*Message); 419d2bfc48SRafael Espindola DiagnosticPrinterRawOStream DP(Stream); 429d2bfc48SRafael Espindola DI.print(DP); 439d2bfc48SRafael Espindola } 449d2bfc48SRafael Espindola 4525963c61SChris Lattner LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, 4670ede484SErick Tryzelaar LLVMMemoryBufferRef MemBuf, 4725963c61SChris Lattner LLVMModuleRef *OutModule, 4825963c61SChris Lattner char **OutMessage) { 493ee23a9eSRafael Espindola MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 503ee23a9eSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 513ee23a9eSRafael Espindola 529d2bfc48SRafael Espindola LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = 539d2bfc48SRafael Espindola Ctx.getDiagnosticHandler(); 549d2bfc48SRafael Espindola void *OldDiagnosticContext = Ctx.getDiagnosticContext(); 553ee23a9eSRafael Espindola std::string Message; 569d2bfc48SRafael Espindola Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true); 573ee23a9eSRafael Espindola 589d2bfc48SRafael Espindola ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 599d2bfc48SRafael Espindola 609d2bfc48SRafael Espindola Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); 619d2bfc48SRafael Espindola 62dcfd6ed1SRafael Espindola if (ModuleOrErr.getError()) { 639d2bfc48SRafael Espindola if (OutMessage) 64dcfd6ed1SRafael Espindola *OutMessage = strdup(Message.c_str()); 652617dcceSCraig Topper *OutModule = wrap((Module *)nullptr); 662b0eed27SGordon Henriksen return 1; 672b0eed27SGordon Henriksen } 682b0eed27SGordon Henriksen 69dcd1dca2SRafael Espindola *OutModule = wrap(ModuleOrErr.get().release()); 702b0eed27SGordon Henriksen return 0; 712b0eed27SGordon Henriksen } 722b0eed27SGordon Henriksen 73*2339ffedSRafael Espindola LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef, 74*2339ffedSRafael Espindola LLVMMemoryBufferRef MemBuf, 75*2339ffedSRafael Espindola LLVMModuleRef *OutModule) { 76*2339ffedSRafael Espindola MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 77*2339ffedSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 78*2339ffedSRafael Espindola 79*2339ffedSRafael Espindola ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 80*2339ffedSRafael Espindola if (ModuleOrErr.getError()) { 81*2339ffedSRafael Espindola *OutModule = wrap((Module *)nullptr); 82*2339ffedSRafael Espindola return 1; 83*2339ffedSRafael Espindola } 84*2339ffedSRafael Espindola 85*2339ffedSRafael Espindola *OutModule = wrap(ModuleOrErr.get().release()); 86*2339ffedSRafael Espindola return 0; 87*2339ffedSRafael Espindola } 88*2339ffedSRafael Espindola 8934eb6d87SGordon Henriksen /* Reads a module from the specified path, returning via the OutModule parameter 9034eb6d87SGordon Henriksen a module provider which performs lazy deserialization. Returns 0 on success. 9134eb6d87SGordon Henriksen Optionally returns a human-readable error message via OutMessage. */ 92ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, 9370ede484SErick Tryzelaar LLVMMemoryBufferRef MemBuf, 94d7f9c250SRafael Espindola LLVMModuleRef *OutM, char **OutMessage) { 95f382b883SRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 96f382b883SRafael Espindola LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = 97f382b883SRafael Espindola Ctx.getDiagnosticHandler(); 98f382b883SRafael Espindola void *OldDiagnosticContext = Ctx.getDiagnosticContext(); 99f382b883SRafael Espindola 10031d44e49SOwen Anderson std::string Message; 101f382b883SRafael Espindola Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true); 102e2c1d77fSRafael Espindola std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 103e2c1d77fSRafael Espindola 104dcd1dca2SRafael Espindola ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 105f382b883SRafael Espindola getLazyBitcodeModule(std::move(Owner), Ctx); 106e2c1d77fSRafael Espindola Owner.release(); 107f382b883SRafael Espindola Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); 10831d44e49SOwen Anderson 109f382b883SRafael Espindola if (ModuleOrErr.getError()) { 1102617dcceSCraig Topper *OutM = wrap((Module *)nullptr); 11134eb6d87SGordon Henriksen if (OutMessage) 112f382b883SRafael Espindola *OutMessage = strdup(Message.c_str()); 11334eb6d87SGordon Henriksen return 1; 11434eb6d87SGordon Henriksen } 11534eb6d87SGordon Henriksen 116dcd1dca2SRafael Espindola *OutM = wrap(ModuleOrErr.get().release()); 1175b6c1e8eSRafael Espindola 11834eb6d87SGordon Henriksen return 0; 119ad0e0cb0SErick Tryzelaar } 120ad0e0cb0SErick Tryzelaar 121*2339ffedSRafael Espindola LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef, 122*2339ffedSRafael Espindola LLVMMemoryBufferRef MemBuf, 123*2339ffedSRafael Espindola LLVMModuleRef *OutM) { 124*2339ffedSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 125*2339ffedSRafael Espindola std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 126*2339ffedSRafael Espindola 127*2339ffedSRafael Espindola ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 128*2339ffedSRafael Espindola getLazyBitcodeModule(std::move(Owner), Ctx); 129*2339ffedSRafael Espindola Owner.release(); 130*2339ffedSRafael Espindola 131*2339ffedSRafael Espindola if (ModuleOrErr.getError()) { 132*2339ffedSRafael Espindola *OutM = wrap((Module *)nullptr); 133*2339ffedSRafael Espindola return 1; 134*2339ffedSRafael Espindola } 135*2339ffedSRafael Espindola 136*2339ffedSRafael Espindola *OutM = wrap(ModuleOrErr.get().release()); 137*2339ffedSRafael Espindola return 0; 138*2339ffedSRafael Espindola } 139*2339ffedSRafael Espindola 140ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 141ad0e0cb0SErick Tryzelaar char **OutMessage) { 142ad0e0cb0SErick Tryzelaar return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM, 143ad0e0cb0SErick Tryzelaar OutMessage); 144ad0e0cb0SErick Tryzelaar } 145*2339ffedSRafael Espindola 146*2339ffedSRafael Espindola LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf, 147*2339ffedSRafael Espindola LLVMModuleRef *OutM) { 148*2339ffedSRafael Espindola return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM); 149*2339ffedSRafael Espindola } 150