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"
112b0eed27SGordon Henriksen #include "llvm/Bitcode/ReaderWriter.h"
123ee23a9eSRafael Espindola #include "llvm/IR/DiagnosticPrinter.h"
139fb823bbSChandler Carruth #include "llvm/IR/LLVMContext.h"
14dec20e43SFilip Pizlo #include "llvm/IR/Module.h"
152b0eed27SGordon Henriksen #include "llvm/Support/MemoryBuffer.h"
163ee23a9eSRafael Espindola #include "llvm/Support/raw_ostream.h"
17579f0713SAnton Korobeynikov #include <cstring>
18ed0881b2SChandler Carruth #include <string>
192b0eed27SGordon Henriksen 
202b0eed27SGordon Henriksen using namespace llvm;
212b0eed27SGordon Henriksen 
2234eb6d87SGordon Henriksen /* Builds a module from the bitcode in the specified memory buffer, returning a
2334eb6d87SGordon Henriksen    reference to the module via the OutModule parameter. Returns 0 on success.
2434eb6d87SGordon Henriksen    Optionally returns a human-readable error message via OutMessage. */
2525963c61SChris Lattner LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
2631d44e49SOwen Anderson                           LLVMModuleRef *OutModule, char **OutMessage) {
27754946c1SDaniel Dunbar   return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule,
28754946c1SDaniel Dunbar                                    OutMessage);
2931d44e49SOwen Anderson }
3031d44e49SOwen Anderson 
3125963c61SChris Lattner LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
3270ede484SErick Tryzelaar                                    LLVMMemoryBufferRef MemBuf,
3325963c61SChris Lattner                                    LLVMModuleRef *OutModule,
3425963c61SChris Lattner                                    char **OutMessage) {
353ee23a9eSRafael Espindola   MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
363ee23a9eSRafael Espindola   LLVMContext &Ctx = *unwrap(ContextRef);
373ee23a9eSRafael Espindola 
383ee23a9eSRafael Espindola   std::string Message;
393ee23a9eSRafael Espindola   raw_string_ostream Stream(Message);
403ee23a9eSRafael Espindola   DiagnosticPrinterRawOStream DP(Stream);
413ee23a9eSRafael Espindola 
42*dcd1dca2SRafael Espindola   ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(
433ee23a9eSRafael Espindola       Buf, Ctx, [&](const DiagnosticInfo &DI) { DI.print(DP); });
44dcfd6ed1SRafael Espindola   if (ModuleOrErr.getError()) {
45dcfd6ed1SRafael Espindola     if (OutMessage) {
46dcfd6ed1SRafael Espindola       Stream.flush();
47dcfd6ed1SRafael Espindola       *OutMessage = strdup(Message.c_str());
48dcfd6ed1SRafael Espindola     }
492617dcceSCraig Topper     *OutModule = wrap((Module*)nullptr);
502b0eed27SGordon Henriksen     return 1;
512b0eed27SGordon Henriksen   }
522b0eed27SGordon Henriksen 
53*dcd1dca2SRafael Espindola   *OutModule = wrap(ModuleOrErr.get().release());
542b0eed27SGordon Henriksen   return 0;
552b0eed27SGordon Henriksen }
562b0eed27SGordon Henriksen 
5734eb6d87SGordon Henriksen /* Reads a module from the specified path, returning via the OutModule parameter
5834eb6d87SGordon Henriksen    a module provider which performs lazy deserialization. Returns 0 on success.
5934eb6d87SGordon Henriksen    Optionally returns a human-readable error message via OutMessage. */
60ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
6170ede484SErick Tryzelaar                                        LLVMMemoryBufferRef MemBuf,
62ad0e0cb0SErick Tryzelaar                                        LLVMModuleRef *OutM,
6331d44e49SOwen Anderson                                        char **OutMessage) {
6431d44e49SOwen Anderson   std::string Message;
65e2c1d77fSRafael Espindola   std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
66e2c1d77fSRafael Espindola 
67*dcd1dca2SRafael Espindola   ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
6868812157SRafael Espindola       getLazyBitcodeModule(std::move(Owner), *unwrap(ContextRef));
69e2c1d77fSRafael Espindola   Owner.release();
7031d44e49SOwen Anderson 
71db4ed0bdSRafael Espindola   if (std::error_code EC = ModuleOrErr.getError()) {
722617dcceSCraig Topper     *OutM = wrap((Module *)nullptr);
7334eb6d87SGordon Henriksen     if (OutMessage)
745b6c1e8eSRafael Espindola       *OutMessage = strdup(EC.message().c_str());
7534eb6d87SGordon Henriksen     return 1;
7634eb6d87SGordon Henriksen   }
7734eb6d87SGordon Henriksen 
78*dcd1dca2SRafael Espindola   *OutM = wrap(ModuleOrErr.get().release());
795b6c1e8eSRafael Espindola 
8034eb6d87SGordon Henriksen   return 0;
81ad0e0cb0SErick Tryzelaar 
82ad0e0cb0SErick Tryzelaar }
83ad0e0cb0SErick Tryzelaar 
84ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
85ad0e0cb0SErick Tryzelaar                               char **OutMessage) {
86ad0e0cb0SErick Tryzelaar   return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
87ad0e0cb0SErick Tryzelaar                                        OutMessage);
88ad0e0cb0SErick Tryzelaar }
89ad0e0cb0SErick Tryzelaar 
90ad0e0cb0SErick Tryzelaar /* Deprecated: Use LLVMGetBitcodeModuleInContext instead. */
91ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
92ad0e0cb0SErick Tryzelaar                                                LLVMMemoryBufferRef MemBuf,
93ad0e0cb0SErick Tryzelaar                                                LLVMModuleProviderRef *OutMP,
94ad0e0cb0SErick Tryzelaar                                                char **OutMessage) {
95ad0e0cb0SErick Tryzelaar   return LLVMGetBitcodeModuleInContext(ContextRef, MemBuf,
96ad0e0cb0SErick Tryzelaar                                        reinterpret_cast<LLVMModuleRef*>(OutMP),
97ad0e0cb0SErick Tryzelaar                                        OutMessage);
98ad0e0cb0SErick Tryzelaar }
99ad0e0cb0SErick Tryzelaar 
100ad0e0cb0SErick Tryzelaar /* Deprecated: Use LLVMGetBitcodeModule instead. */
101ad0e0cb0SErick Tryzelaar LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
102ad0e0cb0SErick Tryzelaar                                       LLVMModuleProviderRef *OutMP,
103ad0e0cb0SErick Tryzelaar                                       char **OutMessage) {
104ad0e0cb0SErick Tryzelaar   return LLVMGetBitcodeModuleProviderInContext(LLVMGetGlobalContext(), MemBuf,
105ad0e0cb0SErick Tryzelaar                                                OutMP, OutMessage);
1062b0eed27SGordon Henriksen }
107