xref: /freebsd/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitReader.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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