1*9880d681SAndroid Build Coastguard Worker //===-- BitReader.cpp -----------------------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "llvm-c/BitReader.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm-c/Core.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/Bitcode/ReaderWriter.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DiagnosticPrinter.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
18*9880d681SAndroid Build Coastguard Worker #include <cstring>
19*9880d681SAndroid Build Coastguard Worker #include <string>
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker using namespace llvm;
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker /* Builds a module from the bitcode in the specified memory buffer, returning a
24*9880d681SAndroid Build Coastguard Worker reference to the module via the OutModule parameter. Returns 0 on success.
25*9880d681SAndroid Build Coastguard Worker Optionally returns a human-readable error message via OutMessage. */
LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule,char ** OutMessage)26*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule,
27*9880d681SAndroid Build Coastguard Worker char **OutMessage) {
28*9880d681SAndroid Build Coastguard Worker return LLVMParseBitcodeInContext(LLVMGetGlobalContext(), MemBuf, OutModule,
29*9880d681SAndroid Build Coastguard Worker OutMessage);
30*9880d681SAndroid Build Coastguard Worker }
31*9880d681SAndroid Build Coastguard Worker
LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule)32*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,
33*9880d681SAndroid Build Coastguard Worker LLVMModuleRef *OutModule) {
34*9880d681SAndroid Build Coastguard Worker return LLVMParseBitcodeInContext2(LLVMGetGlobalContext(), MemBuf, OutModule);
35*9880d681SAndroid Build Coastguard Worker }
36*9880d681SAndroid Build Coastguard Worker
diagnosticHandler(const DiagnosticInfo & DI,void * C)37*9880d681SAndroid Build Coastguard Worker static void diagnosticHandler(const DiagnosticInfo &DI, void *C) {
38*9880d681SAndroid Build Coastguard Worker auto *Message = reinterpret_cast<std::string *>(C);
39*9880d681SAndroid Build Coastguard Worker raw_string_ostream Stream(*Message);
40*9880d681SAndroid Build Coastguard Worker DiagnosticPrinterRawOStream DP(Stream);
41*9880d681SAndroid Build Coastguard Worker DI.print(DP);
42*9880d681SAndroid Build Coastguard Worker }
43*9880d681SAndroid Build Coastguard Worker
LLVMParseBitcodeInContext(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule,char ** OutMessage)44*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
45*9880d681SAndroid Build Coastguard Worker LLVMMemoryBufferRef MemBuf,
46*9880d681SAndroid Build Coastguard Worker LLVMModuleRef *OutModule,
47*9880d681SAndroid Build Coastguard Worker char **OutMessage) {
48*9880d681SAndroid Build Coastguard Worker MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
49*9880d681SAndroid Build Coastguard Worker LLVMContext &Ctx = *unwrap(ContextRef);
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
52*9880d681SAndroid Build Coastguard Worker Ctx.getDiagnosticHandler();
53*9880d681SAndroid Build Coastguard Worker void *OldDiagnosticContext = Ctx.getDiagnosticContext();
54*9880d681SAndroid Build Coastguard Worker std::string Message;
55*9880d681SAndroid Build Coastguard Worker Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true);
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true);
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker if (ModuleOrErr.getError()) {
62*9880d681SAndroid Build Coastguard Worker if (OutMessage)
63*9880d681SAndroid Build Coastguard Worker *OutMessage = strdup(Message.c_str());
64*9880d681SAndroid Build Coastguard Worker *OutModule = wrap((Module *)nullptr);
65*9880d681SAndroid Build Coastguard Worker return 1;
66*9880d681SAndroid Build Coastguard Worker }
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker *OutModule = wrap(ModuleOrErr.get().release());
69*9880d681SAndroid Build Coastguard Worker return 0;
70*9880d681SAndroid Build Coastguard Worker }
71*9880d681SAndroid Build Coastguard Worker
LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule)72*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,
73*9880d681SAndroid Build Coastguard Worker LLVMMemoryBufferRef MemBuf,
74*9880d681SAndroid Build Coastguard Worker LLVMModuleRef *OutModule) {
75*9880d681SAndroid Build Coastguard Worker MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
76*9880d681SAndroid Build Coastguard Worker LLVMContext &Ctx = *unwrap(ContextRef);
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
79*9880d681SAndroid Build Coastguard Worker if (ModuleOrErr.getError()) {
80*9880d681SAndroid Build Coastguard Worker *OutModule = wrap((Module *)nullptr);
81*9880d681SAndroid Build Coastguard Worker return 1;
82*9880d681SAndroid Build Coastguard Worker }
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker *OutModule = wrap(ModuleOrErr.get().release());
85*9880d681SAndroid Build Coastguard Worker return 0;
86*9880d681SAndroid Build Coastguard Worker }
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker /* Reads a module from the specified path, returning via the OutModule parameter
89*9880d681SAndroid Build Coastguard Worker a module provider which performs lazy deserialization. Returns 0 on success.
90*9880d681SAndroid Build Coastguard Worker Optionally returns a human-readable error message via OutMessage. */
LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM,char ** OutMessage)91*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
92*9880d681SAndroid Build Coastguard Worker LLVMMemoryBufferRef MemBuf,
93*9880d681SAndroid Build Coastguard Worker LLVMModuleRef *OutM, char **OutMessage) {
94*9880d681SAndroid Build Coastguard Worker LLVMContext &Ctx = *unwrap(ContextRef);
95*9880d681SAndroid Build Coastguard Worker LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
96*9880d681SAndroid Build Coastguard Worker Ctx.getDiagnosticHandler();
97*9880d681SAndroid Build Coastguard Worker void *OldDiagnosticContext = Ctx.getDiagnosticContext();
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker std::string Message;
100*9880d681SAndroid Build Coastguard Worker Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true);
101*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
104*9880d681SAndroid Build Coastguard Worker getLazyBitcodeModule(std::move(Owner), Ctx);
105*9880d681SAndroid Build Coastguard Worker Owner.release();
106*9880d681SAndroid Build Coastguard Worker Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true);
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker if (ModuleOrErr.getError()) {
109*9880d681SAndroid Build Coastguard Worker *OutM = wrap((Module *)nullptr);
110*9880d681SAndroid Build Coastguard Worker if (OutMessage)
111*9880d681SAndroid Build Coastguard Worker *OutMessage = strdup(Message.c_str());
112*9880d681SAndroid Build Coastguard Worker return 1;
113*9880d681SAndroid Build Coastguard Worker }
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker *OutM = wrap(ModuleOrErr.get().release());
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker return 0;
118*9880d681SAndroid Build Coastguard Worker }
119*9880d681SAndroid Build Coastguard Worker
LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM)120*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,
121*9880d681SAndroid Build Coastguard Worker LLVMMemoryBufferRef MemBuf,
122*9880d681SAndroid Build Coastguard Worker LLVMModuleRef *OutM) {
123*9880d681SAndroid Build Coastguard Worker LLVMContext &Ctx = *unwrap(ContextRef);
124*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
127*9880d681SAndroid Build Coastguard Worker getLazyBitcodeModule(std::move(Owner), Ctx);
128*9880d681SAndroid Build Coastguard Worker Owner.release();
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker if (ModuleOrErr.getError()) {
131*9880d681SAndroid Build Coastguard Worker *OutM = wrap((Module *)nullptr);
132*9880d681SAndroid Build Coastguard Worker return 1;
133*9880d681SAndroid Build Coastguard Worker }
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Worker *OutM = wrap(ModuleOrErr.get().release());
136*9880d681SAndroid Build Coastguard Worker return 0;
137*9880d681SAndroid Build Coastguard Worker }
138*9880d681SAndroid Build Coastguard Worker
LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM,char ** OutMessage)139*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
140*9880d681SAndroid Build Coastguard Worker char **OutMessage) {
141*9880d681SAndroid Build Coastguard Worker return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
142*9880d681SAndroid Build Coastguard Worker OutMessage);
143*9880d681SAndroid Build Coastguard Worker }
144*9880d681SAndroid Build Coastguard Worker
LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM)145*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,
146*9880d681SAndroid Build Coastguard Worker LLVMModuleRef *OutM) {
147*9880d681SAndroid Build Coastguard Worker return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM);
148*9880d681SAndroid Build Coastguard Worker }
149