xref: /aosp_15_r20/external/llvm/lib/Bitcode/Reader/BitReader.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- BitReader.cpp -----------------------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "llvm-c/BitReader.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm-c/Core.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/Bitcode/ReaderWriter.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DiagnosticPrinter.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
18*9880d681SAndroid Build Coastguard Worker #include <cstring>
19*9880d681SAndroid Build Coastguard Worker #include <string>
20*9880d681SAndroid Build Coastguard Worker 
21*9880d681SAndroid Build Coastguard Worker using namespace llvm;
22*9880d681SAndroid Build Coastguard Worker 
23*9880d681SAndroid Build Coastguard Worker /* Builds a module from the bitcode in the specified memory buffer, returning a
24*9880d681SAndroid Build Coastguard Worker    reference to the module via the OutModule parameter. Returns 0 on success.
25*9880d681SAndroid Build Coastguard Worker    Optionally returns a human-readable error message via OutMessage. */
LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule,char ** OutMessage)26*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule,
27*9880d681SAndroid Build Coastguard Worker                           char **OutMessage) {
28*9880d681SAndroid Build Coastguard Worker   return LLVMParseBitcodeInContext(LLVMGetGlobalContext(), MemBuf, OutModule,
29*9880d681SAndroid Build Coastguard Worker                                    OutMessage);
30*9880d681SAndroid Build Coastguard Worker }
31*9880d681SAndroid Build Coastguard Worker 
LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule)32*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,
33*9880d681SAndroid Build Coastguard Worker                            LLVMModuleRef *OutModule) {
34*9880d681SAndroid Build Coastguard Worker   return LLVMParseBitcodeInContext2(LLVMGetGlobalContext(), MemBuf, OutModule);
35*9880d681SAndroid Build Coastguard Worker }
36*9880d681SAndroid Build Coastguard Worker 
diagnosticHandler(const DiagnosticInfo & DI,void * C)37*9880d681SAndroid Build Coastguard Worker static void diagnosticHandler(const DiagnosticInfo &DI, void *C) {
38*9880d681SAndroid Build Coastguard Worker   auto *Message = reinterpret_cast<std::string *>(C);
39*9880d681SAndroid Build Coastguard Worker   raw_string_ostream Stream(*Message);
40*9880d681SAndroid Build Coastguard Worker   DiagnosticPrinterRawOStream DP(Stream);
41*9880d681SAndroid Build Coastguard Worker   DI.print(DP);
42*9880d681SAndroid Build Coastguard Worker }
43*9880d681SAndroid Build Coastguard Worker 
LLVMParseBitcodeInContext(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule,char ** OutMessage)44*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
45*9880d681SAndroid Build Coastguard Worker                                    LLVMMemoryBufferRef MemBuf,
46*9880d681SAndroid Build Coastguard Worker                                    LLVMModuleRef *OutModule,
47*9880d681SAndroid Build Coastguard Worker                                    char **OutMessage) {
48*9880d681SAndroid Build Coastguard Worker   MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
49*9880d681SAndroid Build Coastguard Worker   LLVMContext &Ctx = *unwrap(ContextRef);
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker   LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
52*9880d681SAndroid Build Coastguard Worker       Ctx.getDiagnosticHandler();
53*9880d681SAndroid Build Coastguard Worker   void *OldDiagnosticContext = Ctx.getDiagnosticContext();
54*9880d681SAndroid Build Coastguard Worker   std::string Message;
55*9880d681SAndroid Build Coastguard Worker   Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true);
56*9880d681SAndroid Build Coastguard Worker 
57*9880d681SAndroid Build Coastguard Worker   ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
58*9880d681SAndroid Build Coastguard Worker 
59*9880d681SAndroid Build Coastguard Worker   Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true);
60*9880d681SAndroid Build Coastguard Worker 
61*9880d681SAndroid Build Coastguard Worker   if (ModuleOrErr.getError()) {
62*9880d681SAndroid Build Coastguard Worker     if (OutMessage)
63*9880d681SAndroid Build Coastguard Worker       *OutMessage = strdup(Message.c_str());
64*9880d681SAndroid Build Coastguard Worker     *OutModule = wrap((Module *)nullptr);
65*9880d681SAndroid Build Coastguard Worker     return 1;
66*9880d681SAndroid Build Coastguard Worker   }
67*9880d681SAndroid Build Coastguard Worker 
68*9880d681SAndroid Build Coastguard Worker   *OutModule = wrap(ModuleOrErr.get().release());
69*9880d681SAndroid Build Coastguard Worker   return 0;
70*9880d681SAndroid Build Coastguard Worker }
71*9880d681SAndroid Build Coastguard Worker 
LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule)72*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,
73*9880d681SAndroid Build Coastguard Worker                                     LLVMMemoryBufferRef MemBuf,
74*9880d681SAndroid Build Coastguard Worker                                     LLVMModuleRef *OutModule) {
75*9880d681SAndroid Build Coastguard Worker   MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
76*9880d681SAndroid Build Coastguard Worker   LLVMContext &Ctx = *unwrap(ContextRef);
77*9880d681SAndroid Build Coastguard Worker 
78*9880d681SAndroid Build Coastguard Worker   ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
79*9880d681SAndroid Build Coastguard Worker   if (ModuleOrErr.getError()) {
80*9880d681SAndroid Build Coastguard Worker     *OutModule = wrap((Module *)nullptr);
81*9880d681SAndroid Build Coastguard Worker     return 1;
82*9880d681SAndroid Build Coastguard Worker   }
83*9880d681SAndroid Build Coastguard Worker 
84*9880d681SAndroid Build Coastguard Worker   *OutModule = wrap(ModuleOrErr.get().release());
85*9880d681SAndroid Build Coastguard Worker   return 0;
86*9880d681SAndroid Build Coastguard Worker }
87*9880d681SAndroid Build Coastguard Worker 
88*9880d681SAndroid Build Coastguard Worker /* Reads a module from the specified path, returning via the OutModule parameter
89*9880d681SAndroid Build Coastguard Worker    a module provider which performs lazy deserialization. Returns 0 on success.
90*9880d681SAndroid Build Coastguard Worker    Optionally returns a human-readable error message via OutMessage. */
LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM,char ** OutMessage)91*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
92*9880d681SAndroid Build Coastguard Worker                                        LLVMMemoryBufferRef MemBuf,
93*9880d681SAndroid Build Coastguard Worker                                        LLVMModuleRef *OutM, char **OutMessage) {
94*9880d681SAndroid Build Coastguard Worker   LLVMContext &Ctx = *unwrap(ContextRef);
95*9880d681SAndroid Build Coastguard Worker   LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
96*9880d681SAndroid Build Coastguard Worker       Ctx.getDiagnosticHandler();
97*9880d681SAndroid Build Coastguard Worker   void *OldDiagnosticContext = Ctx.getDiagnosticContext();
98*9880d681SAndroid Build Coastguard Worker 
99*9880d681SAndroid Build Coastguard Worker   std::string Message;
100*9880d681SAndroid Build Coastguard Worker   Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true);
101*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker   ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
104*9880d681SAndroid Build Coastguard Worker       getLazyBitcodeModule(std::move(Owner), Ctx);
105*9880d681SAndroid Build Coastguard Worker   Owner.release();
106*9880d681SAndroid Build Coastguard Worker   Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true);
107*9880d681SAndroid Build Coastguard Worker 
108*9880d681SAndroid Build Coastguard Worker   if (ModuleOrErr.getError()) {
109*9880d681SAndroid Build Coastguard Worker     *OutM = wrap((Module *)nullptr);
110*9880d681SAndroid Build Coastguard Worker     if (OutMessage)
111*9880d681SAndroid Build Coastguard Worker       *OutMessage = strdup(Message.c_str());
112*9880d681SAndroid Build Coastguard Worker     return 1;
113*9880d681SAndroid Build Coastguard Worker   }
114*9880d681SAndroid Build Coastguard Worker 
115*9880d681SAndroid Build Coastguard Worker   *OutM = wrap(ModuleOrErr.get().release());
116*9880d681SAndroid Build Coastguard Worker 
117*9880d681SAndroid Build Coastguard Worker   return 0;
118*9880d681SAndroid Build Coastguard Worker }
119*9880d681SAndroid Build Coastguard Worker 
LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM)120*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,
121*9880d681SAndroid Build Coastguard Worker                                         LLVMMemoryBufferRef MemBuf,
122*9880d681SAndroid Build Coastguard Worker                                         LLVMModuleRef *OutM) {
123*9880d681SAndroid Build Coastguard Worker   LLVMContext &Ctx = *unwrap(ContextRef);
124*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
125*9880d681SAndroid Build Coastguard Worker 
126*9880d681SAndroid Build Coastguard Worker   ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
127*9880d681SAndroid Build Coastguard Worker       getLazyBitcodeModule(std::move(Owner), Ctx);
128*9880d681SAndroid Build Coastguard Worker   Owner.release();
129*9880d681SAndroid Build Coastguard Worker 
130*9880d681SAndroid Build Coastguard Worker   if (ModuleOrErr.getError()) {
131*9880d681SAndroid Build Coastguard Worker     *OutM = wrap((Module *)nullptr);
132*9880d681SAndroid Build Coastguard Worker     return 1;
133*9880d681SAndroid Build Coastguard Worker   }
134*9880d681SAndroid Build Coastguard Worker 
135*9880d681SAndroid Build Coastguard Worker   *OutM = wrap(ModuleOrErr.get().release());
136*9880d681SAndroid Build Coastguard Worker   return 0;
137*9880d681SAndroid Build Coastguard Worker }
138*9880d681SAndroid Build Coastguard Worker 
LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM,char ** OutMessage)139*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
140*9880d681SAndroid Build Coastguard Worker                               char **OutMessage) {
141*9880d681SAndroid Build Coastguard Worker   return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
142*9880d681SAndroid Build Coastguard Worker                                        OutMessage);
143*9880d681SAndroid Build Coastguard Worker }
144*9880d681SAndroid Build Coastguard Worker 
LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM)145*9880d681SAndroid Build Coastguard Worker LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,
146*9880d681SAndroid Build Coastguard Worker                                LLVMModuleRef *OutM) {
147*9880d681SAndroid Build Coastguard Worker   return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM);
148*9880d681SAndroid Build Coastguard Worker }
149