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