1bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen//===-- BitReader.cpp -----------------------------------------------------===//
2bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen//
3bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen//                     The LLVM Compiler Infrastructure
4bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen//
8bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen//===----------------------------------------------------------------------===//
9bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen
10bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen#include "llvm-c/BitReader.h"
11cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm-c/Core.h"
12bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen#include "llvm/Bitcode/ReaderWriter.h"
13ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/DiagnosticPrinter.h"
140b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h"
1540be1e85665d10f5444186f0e7106e368dd735b8Filip Pizlo#include "llvm/IR/Module.h"
16bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen#include "llvm/Support/MemoryBuffer.h"
17ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/raw_ostream.h"
18ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include <cstring>
19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include <string>
20bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen
21bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksenusing namespace llvm;
22bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen
23da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen/* Builds a module from the bitcode in the specified memory buffer, returning a
24da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen   reference to the module via the OutModule parameter. Returns 0 on success.
25d686c8e73f74e37ab5f647b65a12051ee6cbad16Chris Lattner   Optionally returns a human-readable error message via OutMessage. */
26cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarLLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule,
27cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                          char **OutMessage) {
28e44fc85bba960ddffc1e8abaf9f919945ed218b9Daniel Dunbar  return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule,
29e44fc85bba960ddffc1e8abaf9f919945ed218b9Daniel Dunbar                                   OutMessage);
30c8897d9c2f9fcee6061a2c2d380028269026a836Owen Anderson}
31c8897d9c2f9fcee6061a2c2d380028269026a836Owen Anderson
32cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarLLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,
33cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                           LLVMModuleRef *OutModule) {
34cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return LLVMParseBitcodeInContext2(wrap(&getGlobalContext()), MemBuf,
35cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                    OutModule);
36cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
37cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
38cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic void diagnosticHandler(const DiagnosticInfo &DI, void *C) {
39cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  auto *Message = reinterpret_cast<std::string *>(C);
40cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  raw_string_ostream Stream(*Message);
41cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  DiagnosticPrinterRawOStream DP(Stream);
42cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  DI.print(DP);
43cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
44cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
45d686c8e73f74e37ab5f647b65a12051ee6cbad16Chris LattnerLLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
46d686c8e73f74e37ab5f647b65a12051ee6cbad16Chris Lattner                                   LLVMMemoryBufferRef MemBuf,
47d686c8e73f74e37ab5f647b65a12051ee6cbad16Chris Lattner                                   LLVMModuleRef *OutModule,
48d686c8e73f74e37ab5f647b65a12051ee6cbad16Chris Lattner                                   char **OutMessage) {
49ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
50ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  LLVMContext &Ctx = *unwrap(ContextRef);
51ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
52cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
53cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      Ctx.getDiagnosticHandler();
54cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  void *OldDiagnosticContext = Ctx.getDiagnosticContext();
55ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::string Message;
56cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true);
57cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
58cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
59cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
60cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true);
61ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
62ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (ModuleOrErr.getError()) {
63cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (OutMessage)
64ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      *OutMessage = strdup(Message.c_str());
65cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    *OutModule = wrap((Module *)nullptr);
66cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return 1;
67cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
68cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
69cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  *OutModule = wrap(ModuleOrErr.get().release());
70cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return 0;
71cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
72cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
73cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarLLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,
74cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                    LLVMMemoryBufferRef MemBuf,
75cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                    LLVMModuleRef *OutModule) {
76cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
77cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  LLVMContext &Ctx = *unwrap(ContextRef);
78cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
79cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
80cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (ModuleOrErr.getError()) {
81cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    *OutModule = wrap((Module *)nullptr);
82bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen    return 1;
83bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen  }
84170a15e98dc6900df1ae40d03c5f0622d792fb45Joe Abbey
85cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  *OutModule = wrap(ModuleOrErr.get().release());
86da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen  return 0;
87da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen}
88da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen
89da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen/* Reads a module from the specified path, returning via the OutModule parameter
90da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen   a module provider which performs lazy deserialization. Returns 0 on success.
91170a15e98dc6900df1ae40d03c5f0622d792fb45Joe Abbey   Optionally returns a human-readable error message via OutMessage. */
92df7df075b723e926e51555bf5aff6e231279a479Erick TryzelaarLLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
93df7df075b723e926e51555bf5aff6e231279a479Erick Tryzelaar                                       LLVMMemoryBufferRef MemBuf,
94cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                       LLVMModuleRef *OutM, char **OutMessage) {
95cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  LLVMContext &Ctx = *unwrap(ContextRef);
96cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
97cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      Ctx.getDiagnosticHandler();
98cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  void *OldDiagnosticContext = Ctx.getDiagnosticContext();
99cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
100da1435f86ebc9886dd7704294e01d192d79e069cGordon Henriksen  std::string Message;
101cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true);
10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
10337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
104cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
105cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      getLazyBitcodeModule(std::move(Owner), Ctx);
10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Owner.release();
107cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true);
108170a15e98dc6900df1ae40d03c5f0622d792fb45Joe Abbey
109cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (ModuleOrErr.getError()) {
110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *OutM = wrap((Module *)nullptr);
111bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen    if (OutMessage)
112cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      *OutMessage = strdup(Message.c_str());
113bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen    return 1;
114bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen  }
115170a15e98dc6900df1ae40d03c5f0622d792fb45Joe Abbey
116cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  *OutM = wrap(ModuleOrErr.get().release());
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
118bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen  return 0;
119cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
120cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
121cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarLLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,
122cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                        LLVMMemoryBufferRef MemBuf,
123cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                        LLVMModuleRef *OutM) {
124cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  LLVMContext &Ctx = *unwrap(ContextRef);
125cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
126cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
127cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
128cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      getLazyBitcodeModule(std::move(Owner), Ctx);
129cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Owner.release();
130df7df075b723e926e51555bf5aff6e231279a479Erick Tryzelaar
131cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (ModuleOrErr.getError()) {
132cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    *OutM = wrap((Module *)nullptr);
133cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return 1;
134cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
135cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
136cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  *OutM = wrap(ModuleOrErr.get().release());
137cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return 0;
138df7df075b723e926e51555bf5aff6e231279a479Erick Tryzelaar}
139df7df075b723e926e51555bf5aff6e231279a479Erick Tryzelaar
140df7df075b723e926e51555bf5aff6e231279a479Erick TryzelaarLLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
141df7df075b723e926e51555bf5aff6e231279a479Erick Tryzelaar                              char **OutMessage) {
142df7df075b723e926e51555bf5aff6e231279a479Erick Tryzelaar  return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
143df7df075b723e926e51555bf5aff6e231279a479Erick Tryzelaar                                       OutMessage);
144df7df075b723e926e51555bf5aff6e231279a479Erick Tryzelaar}
145df7df075b723e926e51555bf5aff6e231279a479Erick Tryzelaar
146cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarLLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,
147cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                               LLVMModuleRef *OutM) {
148cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM);
149bbc6597f02d108f32b5bdc7711cc67386196017bGordon Henriksen}
150