xref: /openbsd-src/gnu/llvm/llvm/lib/Bitcode/Reader/BitReader.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
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