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