1*0b57cec5SDimitry Andric //===-- BitReader.cpp -----------------------------------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric
9*0b57cec5SDimitry Andric #include "llvm-c/BitReader.h"
10*0b57cec5SDimitry Andric #include "llvm-c/Core.h"
11*0b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeReader.h"
12*0b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
13*0b57cec5SDimitry Andric #include "llvm/IR/Module.h"
14*0b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
15*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
16*0b57cec5SDimitry Andric #include <cstring>
17*0b57cec5SDimitry Andric #include <string>
18*0b57cec5SDimitry Andric
19*0b57cec5SDimitry Andric using namespace llvm;
20*0b57cec5SDimitry Andric
21*0b57cec5SDimitry Andric /* Builds a module from the bitcode in the specified memory buffer, returning a
22*0b57cec5SDimitry Andric reference to the module via the OutModule parameter. Returns 0 on success.
23*0b57cec5SDimitry Andric Optionally returns a human-readable error message via OutMessage. */
LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule,char ** OutMessage)24*0b57cec5SDimitry Andric LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule,
25*0b57cec5SDimitry Andric char **OutMessage) {
26*0b57cec5SDimitry Andric return LLVMParseBitcodeInContext(LLVMGetGlobalContext(), MemBuf, OutModule,
27*0b57cec5SDimitry Andric OutMessage);
28*0b57cec5SDimitry Andric }
29*0b57cec5SDimitry Andric
LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule)30*0b57cec5SDimitry Andric LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,
31*0b57cec5SDimitry Andric LLVMModuleRef *OutModule) {
32*0b57cec5SDimitry Andric return LLVMParseBitcodeInContext2(LLVMGetGlobalContext(), MemBuf, OutModule);
33*0b57cec5SDimitry Andric }
34*0b57cec5SDimitry Andric
LLVMParseBitcodeInContext(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule,char ** OutMessage)35*0b57cec5SDimitry Andric LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
36*0b57cec5SDimitry Andric LLVMMemoryBufferRef MemBuf,
37*0b57cec5SDimitry Andric LLVMModuleRef *OutModule,
38*0b57cec5SDimitry Andric char **OutMessage) {
39*0b57cec5SDimitry Andric MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
40*0b57cec5SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef);
41*0b57cec5SDimitry Andric
42*0b57cec5SDimitry Andric Expected<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
43*0b57cec5SDimitry Andric if (Error Err = ModuleOrErr.takeError()) {
44*0b57cec5SDimitry Andric std::string Message;
45*0b57cec5SDimitry Andric handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
46*0b57cec5SDimitry Andric Message = EIB.message();
47*0b57cec5SDimitry Andric });
48*0b57cec5SDimitry Andric if (OutMessage)
49*0b57cec5SDimitry Andric *OutMessage = strdup(Message.c_str());
50*0b57cec5SDimitry Andric *OutModule = wrap((Module *)nullptr);
51*0b57cec5SDimitry Andric return 1;
52*0b57cec5SDimitry Andric }
53*0b57cec5SDimitry Andric
54*0b57cec5SDimitry Andric *OutModule = wrap(ModuleOrErr.get().release());
55*0b57cec5SDimitry Andric return 0;
56*0b57cec5SDimitry Andric }
57*0b57cec5SDimitry Andric
LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule)58*0b57cec5SDimitry Andric LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,
59*0b57cec5SDimitry Andric LLVMMemoryBufferRef MemBuf,
60*0b57cec5SDimitry Andric LLVMModuleRef *OutModule) {
61*0b57cec5SDimitry Andric MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
62*0b57cec5SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef);
63*0b57cec5SDimitry Andric
64*0b57cec5SDimitry Andric ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
65*0b57cec5SDimitry Andric expectedToErrorOrAndEmitErrors(Ctx, parseBitcodeFile(Buf, Ctx));
66*0b57cec5SDimitry Andric if (ModuleOrErr.getError()) {
67*0b57cec5SDimitry Andric *OutModule = wrap((Module *)nullptr);
68*0b57cec5SDimitry Andric return 1;
69*0b57cec5SDimitry Andric }
70*0b57cec5SDimitry Andric
71*0b57cec5SDimitry Andric *OutModule = wrap(ModuleOrErr.get().release());
72*0b57cec5SDimitry Andric return 0;
73*0b57cec5SDimitry Andric }
74*0b57cec5SDimitry Andric
75*0b57cec5SDimitry Andric /* Reads a module from the specified path, returning via the OutModule parameter
76*0b57cec5SDimitry Andric a module provider which performs lazy deserialization. Returns 0 on success.
77*0b57cec5SDimitry Andric Optionally returns a human-readable error message via OutMessage. */
LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM,char ** OutMessage)78*0b57cec5SDimitry Andric LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
79*0b57cec5SDimitry Andric LLVMMemoryBufferRef MemBuf,
80*0b57cec5SDimitry Andric LLVMModuleRef *OutM, char **OutMessage) {
81*0b57cec5SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef);
82*0b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
83*0b57cec5SDimitry Andric Expected<std::unique_ptr<Module>> ModuleOrErr =
84*0b57cec5SDimitry Andric getOwningLazyBitcodeModule(std::move(Owner), Ctx);
85*0b57cec5SDimitry Andric // Release the buffer if we didn't take ownership of it since we never owned
86*0b57cec5SDimitry Andric // it anyway.
87*0b57cec5SDimitry Andric (void)Owner.release();
88*0b57cec5SDimitry Andric
89*0b57cec5SDimitry Andric if (Error Err = ModuleOrErr.takeError()) {
90*0b57cec5SDimitry Andric std::string Message;
91*0b57cec5SDimitry Andric handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
92*0b57cec5SDimitry Andric Message = EIB.message();
93*0b57cec5SDimitry Andric });
94*0b57cec5SDimitry Andric if (OutMessage)
95*0b57cec5SDimitry Andric *OutMessage = strdup(Message.c_str());
96*0b57cec5SDimitry Andric *OutM = wrap((Module *)nullptr);
97*0b57cec5SDimitry Andric return 1;
98*0b57cec5SDimitry Andric }
99*0b57cec5SDimitry Andric
100*0b57cec5SDimitry Andric *OutM = wrap(ModuleOrErr.get().release());
101*0b57cec5SDimitry Andric
102*0b57cec5SDimitry Andric return 0;
103*0b57cec5SDimitry Andric }
104*0b57cec5SDimitry Andric
LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM)105*0b57cec5SDimitry Andric LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,
106*0b57cec5SDimitry Andric LLVMMemoryBufferRef MemBuf,
107*0b57cec5SDimitry Andric LLVMModuleRef *OutM) {
108*0b57cec5SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef);
109*0b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
110*0b57cec5SDimitry Andric
111*0b57cec5SDimitry Andric ErrorOr<std::unique_ptr<Module>> ModuleOrErr = expectedToErrorOrAndEmitErrors(
112*0b57cec5SDimitry Andric Ctx, getOwningLazyBitcodeModule(std::move(Owner), Ctx));
113*0b57cec5SDimitry Andric Owner.release();
114*0b57cec5SDimitry Andric
115*0b57cec5SDimitry Andric if (ModuleOrErr.getError()) {
116*0b57cec5SDimitry Andric *OutM = wrap((Module *)nullptr);
117*0b57cec5SDimitry Andric return 1;
118*0b57cec5SDimitry Andric }
119*0b57cec5SDimitry Andric
120*0b57cec5SDimitry Andric *OutM = wrap(ModuleOrErr.get().release());
121*0b57cec5SDimitry Andric return 0;
122*0b57cec5SDimitry Andric }
123*0b57cec5SDimitry Andric
LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM,char ** OutMessage)124*0b57cec5SDimitry Andric LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
125*0b57cec5SDimitry Andric char **OutMessage) {
126*0b57cec5SDimitry Andric return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
127*0b57cec5SDimitry Andric OutMessage);
128*0b57cec5SDimitry Andric }
129*0b57cec5SDimitry Andric
LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM)130*0b57cec5SDimitry Andric LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,
131*0b57cec5SDimitry Andric LLVMModuleRef *OutM) {
132*0b57cec5SDimitry Andric return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM);
133*0b57cec5SDimitry Andric }
134