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. */ 2625963c61SChris Lattner LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, 2731d44e49SOwen Anderson LLVMModuleRef *OutModule, char **OutMessage) { 28754946c1SDaniel Dunbar return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule, 29754946c1SDaniel Dunbar OutMessage); 3031d44e49SOwen Anderson } 3131d44e49SOwen Anderson 329d2bfc48SRafael Espindola static void diagnosticHandler(const DiagnosticInfo &DI, void *C) { 339d2bfc48SRafael Espindola auto *Message = reinterpret_cast<std::string *>(C); 349d2bfc48SRafael Espindola raw_string_ostream Stream(*Message); 359d2bfc48SRafael Espindola DiagnosticPrinterRawOStream DP(Stream); 369d2bfc48SRafael Espindola DI.print(DP); 379d2bfc48SRafael Espindola } 389d2bfc48SRafael Espindola 3925963c61SChris Lattner LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, 4070ede484SErick Tryzelaar LLVMMemoryBufferRef MemBuf, 4125963c61SChris Lattner LLVMModuleRef *OutModule, 4225963c61SChris Lattner char **OutMessage) { 433ee23a9eSRafael Espindola MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); 443ee23a9eSRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 453ee23a9eSRafael Espindola 469d2bfc48SRafael Espindola LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = 479d2bfc48SRafael Espindola Ctx.getDiagnosticHandler(); 489d2bfc48SRafael Espindola void *OldDiagnosticContext = Ctx.getDiagnosticContext(); 493ee23a9eSRafael Espindola std::string Message; 509d2bfc48SRafael Espindola Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true); 513ee23a9eSRafael Espindola 529d2bfc48SRafael Espindola ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx); 539d2bfc48SRafael Espindola 549d2bfc48SRafael Espindola Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); 559d2bfc48SRafael Espindola 56dcfd6ed1SRafael Espindola if (ModuleOrErr.getError()) { 579d2bfc48SRafael Espindola if (OutMessage) 58dcfd6ed1SRafael Espindola *OutMessage = strdup(Message.c_str()); 592617dcceSCraig Topper *OutModule = wrap((Module*)nullptr); 602b0eed27SGordon Henriksen return 1; 612b0eed27SGordon Henriksen } 622b0eed27SGordon Henriksen 63dcd1dca2SRafael Espindola *OutModule = wrap(ModuleOrErr.get().release()); 642b0eed27SGordon Henriksen return 0; 652b0eed27SGordon Henriksen } 662b0eed27SGordon Henriksen 6734eb6d87SGordon Henriksen /* Reads a module from the specified path, returning via the OutModule parameter 6834eb6d87SGordon Henriksen a module provider which performs lazy deserialization. Returns 0 on success. 6934eb6d87SGordon Henriksen Optionally returns a human-readable error message via OutMessage. */ 70ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, 7170ede484SErick Tryzelaar LLVMMemoryBufferRef MemBuf, 72ad0e0cb0SErick Tryzelaar LLVMModuleRef *OutM, 7331d44e49SOwen Anderson char **OutMessage) { 74*f382b883SRafael Espindola LLVMContext &Ctx = *unwrap(ContextRef); 75*f382b883SRafael Espindola LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = 76*f382b883SRafael Espindola Ctx.getDiagnosticHandler(); 77*f382b883SRafael Espindola void *OldDiagnosticContext = Ctx.getDiagnosticContext(); 78*f382b883SRafael Espindola 7931d44e49SOwen Anderson std::string Message; 80*f382b883SRafael Espindola Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true); 81e2c1d77fSRafael Espindola std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); 82e2c1d77fSRafael Espindola 83dcd1dca2SRafael Espindola ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 84*f382b883SRafael Espindola getLazyBitcodeModule(std::move(Owner), Ctx); 85e2c1d77fSRafael Espindola Owner.release(); 86*f382b883SRafael Espindola Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); 8731d44e49SOwen Anderson 88*f382b883SRafael Espindola if (ModuleOrErr.getError()) { 892617dcceSCraig Topper *OutM = wrap((Module *)nullptr); 9034eb6d87SGordon Henriksen if (OutMessage) 91*f382b883SRafael Espindola *OutMessage = strdup(Message.c_str()); 9234eb6d87SGordon Henriksen return 1; 9334eb6d87SGordon Henriksen } 9434eb6d87SGordon Henriksen 95dcd1dca2SRafael Espindola *OutM = wrap(ModuleOrErr.get().release()); 965b6c1e8eSRafael Espindola 9734eb6d87SGordon Henriksen return 0; 98ad0e0cb0SErick Tryzelaar 99ad0e0cb0SErick Tryzelaar } 100ad0e0cb0SErick Tryzelaar 101ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 102ad0e0cb0SErick Tryzelaar char **OutMessage) { 103ad0e0cb0SErick Tryzelaar return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM, 104ad0e0cb0SErick Tryzelaar OutMessage); 105ad0e0cb0SErick Tryzelaar } 106