xref: /freebsd/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitReader.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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. */
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 
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 
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 
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. */
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 
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 
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 
130*0b57cec5SDimitry Andric LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,
131*0b57cec5SDimitry Andric                                LLVMModuleRef *OutM) {
132*0b57cec5SDimitry Andric   return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM);
133*0b57cec5SDimitry Andric }
134