1009b1c42SEd Schouten //===-- BitReader.cpp -----------------------------------------------------===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten
9009b1c42SEd Schouten #include "llvm-c/BitReader.h"
10dd58ef01SDimitry Andric #include "llvm-c/Core.h"
11b915e9e0SDimitry Andric #include "llvm/Bitcode/BitcodeReader.h"
124a16efa3SDimitry Andric #include "llvm/IR/LLVMContext.h"
1359d6cff9SDimitry Andric #include "llvm/IR/Module.h"
14009b1c42SEd Schouten #include "llvm/Support/MemoryBuffer.h"
15009b1c42SEd Schouten #include <cstring>
164a16efa3SDimitry Andric #include <string>
17009b1c42SEd Schouten
18009b1c42SEd Schouten using namespace llvm;
19009b1c42SEd Schouten
20009b1c42SEd Schouten /* Builds a module from the bitcode in the specified memory buffer, returning a
21009b1c42SEd Schouten reference to the module via the OutModule parameter. Returns 0 on success.
22009b1c42SEd Schouten Optionally returns a human-readable error message via OutMessage. */
LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule,char ** OutMessage)23dd58ef01SDimitry Andric LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule,
24dd58ef01SDimitry Andric char **OutMessage) {
2501095a5dSDimitry Andric return LLVMParseBitcodeInContext(LLVMGetGlobalContext(), MemBuf, OutModule,
266fe5c7aaSRoman Divacky OutMessage);
2718f153bdSEd Schouten }
2818f153bdSEd Schouten
LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule)29dd58ef01SDimitry Andric LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,
30dd58ef01SDimitry Andric LLVMModuleRef *OutModule) {
3101095a5dSDimitry Andric return LLVMParseBitcodeInContext2(LLVMGetGlobalContext(), MemBuf, OutModule);
32dd58ef01SDimitry Andric }
33dd58ef01SDimitry Andric
LLVMParseBitcodeInContext(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule,char ** OutMessage)34829000e0SRoman Divacky LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
3559850d08SRoman Divacky LLVMMemoryBufferRef MemBuf,
36829000e0SRoman Divacky LLVMModuleRef *OutModule,
37829000e0SRoman Divacky char **OutMessage) {
38608e6659SDimitry Andric MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
39608e6659SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef);
40608e6659SDimitry Andric
41b915e9e0SDimitry Andric Expected<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
42b915e9e0SDimitry Andric if (Error Err = ModuleOrErr.takeError()) {
43608e6659SDimitry Andric std::string Message;
44b915e9e0SDimitry Andric handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
45b915e9e0SDimitry Andric Message = EIB.message();
46b915e9e0SDimitry Andric });
47dd58ef01SDimitry Andric if (OutMessage)
48608e6659SDimitry Andric *OutMessage = strdup(Message.c_str());
49dd58ef01SDimitry Andric *OutModule = wrap((Module *)nullptr);
50dd58ef01SDimitry Andric return 1;
51608e6659SDimitry Andric }
52dd58ef01SDimitry Andric
53dd58ef01SDimitry Andric *OutModule = wrap(ModuleOrErr.get().release());
54dd58ef01SDimitry Andric return 0;
55dd58ef01SDimitry Andric }
56dd58ef01SDimitry Andric
LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutModule)57dd58ef01SDimitry Andric LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,
58dd58ef01SDimitry Andric LLVMMemoryBufferRef MemBuf,
59dd58ef01SDimitry Andric LLVMModuleRef *OutModule) {
60dd58ef01SDimitry Andric MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
61dd58ef01SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef);
62dd58ef01SDimitry Andric
63b915e9e0SDimitry Andric ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
64b915e9e0SDimitry Andric expectedToErrorOrAndEmitErrors(Ctx, parseBitcodeFile(Buf, Ctx));
65dd58ef01SDimitry Andric if (ModuleOrErr.getError()) {
665ca98fd9SDimitry Andric *OutModule = wrap((Module *)nullptr);
67009b1c42SEd Schouten return 1;
68009b1c42SEd Schouten }
69009b1c42SEd Schouten
703a0822f0SDimitry Andric *OutModule = wrap(ModuleOrErr.get().release());
71009b1c42SEd Schouten return 0;
72009b1c42SEd Schouten }
73009b1c42SEd Schouten
74009b1c42SEd Schouten /* Reads a module from the specified path, returning via the OutModule parameter
75009b1c42SEd Schouten a module provider which performs lazy deserialization. Returns 0 on success.
76009b1c42SEd Schouten Optionally returns a human-readable error message via OutMessage. */
LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM,char ** OutMessage)7767a71b31SRoman Divacky LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
7859850d08SRoman Divacky LLVMMemoryBufferRef MemBuf,
79dd58ef01SDimitry Andric LLVMModuleRef *OutM, char **OutMessage) {
80dd58ef01SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef);
8167c32a98SDimitry Andric std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
82b915e9e0SDimitry Andric Expected<std::unique_ptr<Module>> ModuleOrErr =
83b915e9e0SDimitry Andric getOwningLazyBitcodeModule(std::move(Owner), Ctx);
84b915e9e0SDimitry Andric // Release the buffer if we didn't take ownership of it since we never owned
85b915e9e0SDimitry Andric // it anyway.
86b915e9e0SDimitry Andric (void)Owner.release();
8767c32a98SDimitry Andric
88b915e9e0SDimitry Andric if (Error Err = ModuleOrErr.takeError()) {
89b915e9e0SDimitry Andric std::string Message;
90b915e9e0SDimitry Andric handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
91b915e9e0SDimitry Andric Message = EIB.message();
92b915e9e0SDimitry Andric });
93009b1c42SEd Schouten if (OutMessage)
94dd58ef01SDimitry Andric *OutMessage = strdup(Message.c_str());
95b915e9e0SDimitry Andric *OutM = wrap((Module *)nullptr);
96009b1c42SEd Schouten return 1;
97009b1c42SEd Schouten }
98009b1c42SEd Schouten
993a0822f0SDimitry Andric *OutM = wrap(ModuleOrErr.get().release());
1005ca98fd9SDimitry Andric
101009b1c42SEd Schouten return 0;
102dd58ef01SDimitry Andric }
10367a71b31SRoman Divacky
LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM)104dd58ef01SDimitry Andric LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,
105dd58ef01SDimitry Andric LLVMMemoryBufferRef MemBuf,
106dd58ef01SDimitry Andric LLVMModuleRef *OutM) {
107dd58ef01SDimitry Andric LLVMContext &Ctx = *unwrap(ContextRef);
108dd58ef01SDimitry Andric std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
109dd58ef01SDimitry Andric
110b915e9e0SDimitry Andric ErrorOr<std::unique_ptr<Module>> ModuleOrErr = expectedToErrorOrAndEmitErrors(
111b915e9e0SDimitry Andric Ctx, getOwningLazyBitcodeModule(std::move(Owner), Ctx));
112dd58ef01SDimitry Andric Owner.release();
113dd58ef01SDimitry Andric
114dd58ef01SDimitry Andric if (ModuleOrErr.getError()) {
115dd58ef01SDimitry Andric *OutM = wrap((Module *)nullptr);
116dd58ef01SDimitry Andric return 1;
117dd58ef01SDimitry Andric }
118dd58ef01SDimitry Andric
119dd58ef01SDimitry Andric *OutM = wrap(ModuleOrErr.get().release());
120dd58ef01SDimitry Andric return 0;
12167a71b31SRoman Divacky }
12267a71b31SRoman Divacky
LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM,char ** OutMessage)12367a71b31SRoman Divacky LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
12467a71b31SRoman Divacky char **OutMessage) {
12567a71b31SRoman Divacky return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
12667a71b31SRoman Divacky OutMessage);
12767a71b31SRoman Divacky }
12867a71b31SRoman Divacky
LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM)129dd58ef01SDimitry Andric LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,
130dd58ef01SDimitry Andric LLVMModuleRef *OutM) {
131dd58ef01SDimitry Andric return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM);
132009b1c42SEd Schouten }
133