1f22ef01cSRoman Divacky //===-- BitReader.cpp -----------------------------------------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky 
10f22ef01cSRoman Divacky #include "llvm-c/BitReader.h"
11f22ef01cSRoman Divacky #include "llvm/Bitcode/ReaderWriter.h"
12*44f7b0dcSDimitry Andric #include "llvm/IR/DiagnosticPrinter.h"
13139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h"
14284c1978SDimitry Andric #include "llvm/IR/Module.h"
15f22ef01cSRoman Divacky #include "llvm/Support/MemoryBuffer.h"
16*44f7b0dcSDimitry Andric #include "llvm/Support/raw_ostream.h"
17f22ef01cSRoman Divacky #include <cstring>
18139f7f9bSDimitry Andric #include <string>
19f22ef01cSRoman Divacky 
20f22ef01cSRoman Divacky using namespace llvm;
21f22ef01cSRoman Divacky 
22f22ef01cSRoman Divacky /* Builds a module from the bitcode in the specified memory buffer, returning a
23f22ef01cSRoman Divacky    reference to the module via the OutModule parameter. Returns 0 on success.
24f22ef01cSRoman Divacky    Optionally returns a human-readable error message via OutMessage. */
25f22ef01cSRoman Divacky LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
26f22ef01cSRoman Divacky                           LLVMModuleRef *OutModule, char **OutMessage) {
27f22ef01cSRoman Divacky   return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule,
28f22ef01cSRoman Divacky                                    OutMessage);
29f22ef01cSRoman Divacky }
30f22ef01cSRoman Divacky 
31f22ef01cSRoman Divacky LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
32f22ef01cSRoman Divacky                                    LLVMMemoryBufferRef MemBuf,
33f22ef01cSRoman Divacky                                    LLVMModuleRef *OutModule,
34f22ef01cSRoman Divacky                                    char **OutMessage) {
35*44f7b0dcSDimitry Andric   MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
36*44f7b0dcSDimitry Andric   LLVMContext &Ctx = *unwrap(ContextRef);
37*44f7b0dcSDimitry Andric 
38*44f7b0dcSDimitry Andric   std::string Message;
39*44f7b0dcSDimitry Andric   raw_string_ostream Stream(Message);
40*44f7b0dcSDimitry Andric   DiagnosticPrinterRawOStream DP(Stream);
41*44f7b0dcSDimitry Andric 
42*44f7b0dcSDimitry Andric   ErrorOr<Module *> ModuleOrErr = parseBitcodeFile(
43*44f7b0dcSDimitry Andric       Buf, Ctx, [&](const DiagnosticInfo &DI) { DI.print(DP); });
44*44f7b0dcSDimitry Andric   if (ModuleOrErr.getError()) {
45*44f7b0dcSDimitry Andric     if (OutMessage) {
46*44f7b0dcSDimitry Andric       Stream.flush();
47*44f7b0dcSDimitry Andric       *OutMessage = strdup(Message.c_str());
48*44f7b0dcSDimitry Andric     }
4991bc56edSDimitry Andric     *OutModule = wrap((Module*)nullptr);
50f22ef01cSRoman Divacky     return 1;
51f22ef01cSRoman Divacky   }
52f22ef01cSRoman Divacky 
5391bc56edSDimitry Andric   *OutModule = wrap(ModuleOrErr.get());
54f22ef01cSRoman Divacky   return 0;
55f22ef01cSRoman Divacky }
56f22ef01cSRoman Divacky 
57f22ef01cSRoman Divacky /* Reads a module from the specified path, returning via the OutModule parameter
58f22ef01cSRoman Divacky    a module provider which performs lazy deserialization. Returns 0 on success.
59f22ef01cSRoman Divacky    Optionally returns a human-readable error message via OutMessage. */
60f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
61f22ef01cSRoman Divacky                                        LLVMMemoryBufferRef MemBuf,
62f22ef01cSRoman Divacky                                        LLVMModuleRef *OutM,
63f22ef01cSRoman Divacky                                        char **OutMessage) {
64f22ef01cSRoman Divacky   std::string Message;
6539d628a0SDimitry Andric   std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
6639d628a0SDimitry Andric 
6791bc56edSDimitry Andric   ErrorOr<Module *> ModuleOrErr =
6839d628a0SDimitry Andric       getLazyBitcodeModule(std::move(Owner), *unwrap(ContextRef));
6939d628a0SDimitry Andric   Owner.release();
70f22ef01cSRoman Divacky 
7191bc56edSDimitry Andric   if (std::error_code EC = ModuleOrErr.getError()) {
7291bc56edSDimitry Andric     *OutM = wrap((Module *)nullptr);
73f22ef01cSRoman Divacky     if (OutMessage)
7491bc56edSDimitry Andric       *OutMessage = strdup(EC.message().c_str());
75f22ef01cSRoman Divacky     return 1;
76f22ef01cSRoman Divacky   }
77f22ef01cSRoman Divacky 
7891bc56edSDimitry Andric   *OutM = wrap(ModuleOrErr.get());
7991bc56edSDimitry Andric 
80f22ef01cSRoman Divacky   return 0;
81f22ef01cSRoman Divacky 
82f22ef01cSRoman Divacky }
83f22ef01cSRoman Divacky 
84f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
85f22ef01cSRoman Divacky                               char **OutMessage) {
86f22ef01cSRoman Divacky   return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
87f22ef01cSRoman Divacky                                        OutMessage);
88f22ef01cSRoman Divacky }
89f22ef01cSRoman Divacky 
90f22ef01cSRoman Divacky /* Deprecated: Use LLVMGetBitcodeModuleInContext instead. */
91f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
92f22ef01cSRoman Divacky                                                LLVMMemoryBufferRef MemBuf,
93f22ef01cSRoman Divacky                                                LLVMModuleProviderRef *OutMP,
94f22ef01cSRoman Divacky                                                char **OutMessage) {
95f22ef01cSRoman Divacky   return LLVMGetBitcodeModuleInContext(ContextRef, MemBuf,
96f22ef01cSRoman Divacky                                        reinterpret_cast<LLVMModuleRef*>(OutMP),
97f22ef01cSRoman Divacky                                        OutMessage);
98f22ef01cSRoman Divacky }
99f22ef01cSRoman Divacky 
100f22ef01cSRoman Divacky /* Deprecated: Use LLVMGetBitcodeModule instead. */
101f22ef01cSRoman Divacky LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
102f22ef01cSRoman Divacky                                       LLVMModuleProviderRef *OutMP,
103f22ef01cSRoman Divacky                                       char **OutMessage) {
104f22ef01cSRoman Divacky   return LLVMGetBitcodeModuleProviderInContext(LLVMGetGlobalContext(), MemBuf,
105f22ef01cSRoman Divacky                                                OutMP, OutMessage);
106f22ef01cSRoman Divacky }
107